LCOV - code coverage report
Current view: top level - libreoffice/unotools/source/ucbhelper - ucbhelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 49 181 27.1 %
Date: 2012-12-27 Functions: 8 17 47.1 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "sal/config.h"
      21             : 
      22             : #include <cassert>
      23             : #include <vector>
      24             : 
      25             : #include "com/sun/star/lang/XMultiServiceFactory.hpp"
      26             : #include "com/sun/star/sdbc/XResultSet.hpp"
      27             : #include "com/sun/star/task/XInteractionHandler.hpp"
      28             : #include "com/sun/star/ucb/CommandAbortedException.hpp"
      29             : #include "com/sun/star/ucb/ContentInfo.hpp"
      30             : #include "com/sun/star/ucb/ContentInfoAttribute.hpp"
      31             : #include "com/sun/star/ucb/IOErrorCode.hpp"
      32             : #include "com/sun/star/ucb/InteractiveIOException.hpp"
      33             : #include "com/sun/star/ucb/NameClashException.hpp"
      34             : #include "com/sun/star/ucb/UniversalContentBroker.hpp"
      35             : #include "com/sun/star/ucb/XCommandEnvironment.hpp"
      36             : #include "com/sun/star/ucb/XContentAccess.hpp"
      37             : #include "com/sun/star/ucb/XContentIdentifier.hpp"
      38             : #include "com/sun/star/ucb/XProgressHandler.hpp"
      39             : #include "com/sun/star/ucb/XUniversalContentBroker.hpp"
      40             : #include "com/sun/star/uno/Any.hxx"
      41             : #include "com/sun/star/uno/Exception.hpp"
      42             : #include "com/sun/star/uno/Reference.hxx"
      43             : #include "com/sun/star/uno/RuntimeException.hpp"
      44             : #include "com/sun/star/uno/Sequence.hxx"
      45             : #include "com/sun/star/util/DateTime.hpp"
      46             : #include "comphelper/processfactory.hxx"
      47             : #include "cppuhelper/exc_hlp.hxx"
      48             : #include "osl/file.hxx"
      49             : #include "rtl/string.h"
      50             : #include "rtl/ustring.h"
      51             : #include "rtl/ustring.hxx"
      52             : #include "sal/log.hxx"
      53             : #include "sal/types.h"
      54             : #include "tools/datetime.hxx"
      55             : #include "tools/urlobj.hxx"
      56             : #include "ucbhelper/commandenvironment.hxx"
      57             : #include "ucbhelper/content.hxx"
      58             : #include "unotools/localfilehelper.hxx"
      59             : #include "unotools/ucbhelper.hxx"
      60             : 
      61             : namespace {
      62             : 
      63       10061 : rtl::OUString canonic(rtl::OUString const & url) {
      64       10061 :     INetURLObject o(url);
      65             :     SAL_WARN_IF(o.HasError(), "unotools", "Invalid URL \"" << url << '"');
      66       10061 :     return o.GetMainURL(INetURLObject::NO_DECODE);
      67             : }
      68             : 
      69         651 : ucbhelper::Content content(rtl::OUString const & url) {
      70             :     return ucbhelper::Content(
      71             :         canonic(url),
      72             :         css::uno::Reference<css::ucb::XCommandEnvironment>(),
      73         651 :         comphelper::getProcessComponentContext());
      74             : }
      75             : 
      76           8 : ucbhelper::Content content(INetURLObject const & url) {
      77             :     return ucbhelper::Content(
      78             :         url.GetMainURL(INetURLObject::NO_DECODE),
      79             :         css::uno::Reference<css::ucb::XCommandEnvironment>(),
      80           8 :         comphelper::getProcessComponentContext());
      81             : }
      82             : 
      83           0 : std::vector<rtl::OUString> getContents(rtl::OUString const & url) {
      84             :     try {
      85           0 :         std::vector<rtl::OUString> cs;
      86           0 :         ucbhelper::Content c(content(url));
      87           0 :         css::uno::Sequence<rtl::OUString> args(1);
      88           0 :         args[0] = rtl::OUString("Title");
      89             :         css::uno::Reference<css::sdbc::XResultSet> res(
      90             :             c.createCursor(args, ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS),
      91           0 :             css::uno::UNO_SET_THROW);
      92             :         css::uno::Reference<com::sun::star::ucb::XContentAccess> acc(
      93           0 :             res, css::uno::UNO_QUERY_THROW);
      94           0 :         while (res->next()) {
      95           0 :             cs.push_back(acc->queryContentIdentifierString());
      96             :         }
      97           0 :         return cs;
      98           0 :     } catch (css::uno::RuntimeException const &) {
      99           0 :         throw;
     100           0 :     } catch (css::ucb::CommandAbortedException const &) {
     101             :         assert(false); // this cannot happen
     102           0 :         throw;
     103           0 :     } catch (css::uno::Exception const &) {
     104           0 :         css::uno::Any e(cppu::getCaughtException());
     105             :         SAL_INFO(
     106             :             "unotools",
     107             :             "getContents(" << url << ") " << e.getValueType().getTypeName()
     108             :                 << " \"" << e.get<css::uno::Exception>().Message << '"');
     109           0 :         return std::vector<rtl::OUString>();
     110             :     }
     111             : }
     112             : 
     113           0 : rtl::OUString getCasePreservingUrl(INetURLObject url) {
     114             :     return
     115             :         content(url).executeCommand(
     116             :             rtl::OUString("getCasePreservingURL"),
     117             :             css::uno::Any()).
     118           0 :         get<rtl::OUString>();
     119             : }
     120             : 
     121           0 : DateTime convert(css::util::DateTime const & dt) {
     122             :     return DateTime(
     123             :         Date(dt.Day, dt.Month, dt.Year),
     124           0 :         Time(dt.Hours, dt.Minutes, dt.Seconds, dt.HundredthSeconds));
     125             : }
     126             : 
     127             : }
     128             : 
     129         397 : bool utl::UCBContentHelper::IsDocument(rtl::OUString const & url) {
     130             :     try {
     131         397 :         return content(url).isDocument();
     132           0 :     } catch (css::uno::RuntimeException const &) {
     133           0 :         throw;
     134           0 :     } catch (css::ucb::CommandAbortedException const &) {
     135             :         assert(false); // this cannot happen
     136           0 :         throw;
     137          82 :     } catch (css::uno::Exception const &) {
     138          41 :         css::uno::Any e(cppu::getCaughtException());
     139             :         SAL_INFO(
     140             :             "unotools",
     141             :             "UCBContentHelper::IsDocument(" << url << ") "
     142             :                 << e.getValueType().getTypeName() << " \""
     143             :                 << e.get<css::uno::Exception>().Message << '"');
     144          41 :         return false;
     145             :     }
     146             : }
     147             : 
     148           0 : css::uno::Any utl::UCBContentHelper::GetProperty(
     149             :     rtl::OUString const & url, rtl::OUString const & property)
     150             : {
     151             :     try {
     152           0 :         return content(url).getPropertyValue(property);
     153           0 :     } catch (css::uno::RuntimeException const &) {
     154           0 :         throw;
     155           0 :     } catch (css::ucb::CommandAbortedException const &) {
     156             :         assert(false); // this cannot happen
     157           0 :         throw;
     158           0 :     } catch (css::uno::Exception const &) {
     159           0 :         css::uno::Any e(cppu::getCaughtException());
     160             :         SAL_INFO(
     161             :             "unotools",
     162             :             "UCBContentHelper::GetProperty(" << url << ", " << property << ") "
     163             :                 << e.getValueType().getTypeName() << " \""
     164             :                 << e.get<css::uno::Exception>().Message << '"');
     165           0 :         return css::uno::Any();
     166             :     }
     167             : }
     168             : 
     169         195 : bool utl::UCBContentHelper::IsFolder(rtl::OUString const & url) {
     170             :     try {
     171         195 :         return content(url).isFolder();
     172           0 :     } catch (css::uno::RuntimeException const &) {
     173           0 :         throw;
     174           0 :     } catch (css::ucb::CommandAbortedException const &) {
     175             :         assert(false); // this cannot happen
     176           0 :         throw;
     177          74 :     } catch (css::uno::Exception const &) {
     178          37 :         css::uno::Any e(cppu::getCaughtException());
     179             :         SAL_INFO(
     180             :             "unotools",
     181             :             "UCBContentHelper::IsFolder(" << url << ") "
     182             :                 << e.getValueType().getTypeName() << " \""
     183             :                 << e.get<css::uno::Exception>().Message << '"');
     184          37 :         return false;
     185             :     }
     186             : }
     187             : 
     188           0 : bool utl::UCBContentHelper::GetTitle(
     189             :     rtl::OUString const & url, rtl::OUString * title)
     190             : {
     191             :     assert(title != 0);
     192             :     try {
     193           0 :         return content(url).getPropertyValue(rtl::OUString("Title")) >>= *title;
     194           0 :     } catch (css::uno::RuntimeException const &) {
     195           0 :         throw;
     196           0 :     } catch (css::ucb::CommandAbortedException const &) {
     197             :         assert(false); // this cannot happen
     198           0 :         throw;
     199           0 :     } catch (css::uno::Exception const &) {
     200           0 :         css::uno::Any e(cppu::getCaughtException());
     201             :         SAL_INFO(
     202             :             "unotools",
     203             :             "UCBContentHelper::GetTitle(" << url << ") "
     204             :                 << e.getValueType().getTypeName() << " \""
     205             :                 << e.get<css::uno::Exception>().Message << '"');
     206           0 :         return false;
     207             :     }
     208             : }
     209             : 
     210          59 : bool utl::UCBContentHelper::Kill(rtl::OUString const & url) {
     211             :     try {
     212             :         content(url).executeCommand(
     213             :             rtl::OUString("delete"),
     214          59 :             css::uno::makeAny(true));
     215          59 :         return true;
     216           0 :     } catch (css::uno::RuntimeException const &) {
     217           0 :         throw;
     218           0 :     } catch (css::ucb::CommandAbortedException const &) {
     219             :         assert(false); // this cannot happen
     220           0 :         throw;
     221           0 :     } catch (css::uno::Exception const &) {
     222           0 :         css::uno::Any e(cppu::getCaughtException());
     223             :         SAL_INFO(
     224             :             "unotools",
     225             :             "UCBContentHelper::Kill(" << url << ") "
     226             :                 << e.getValueType().getTypeName() << " \""
     227             :                 << e.get<css::uno::Exception>().Message << '"');
     228           0 :         return false;
     229             :     }
     230             : }
     231             : 
     232          14 : bool utl::UCBContentHelper::MakeFolder(
     233             :     ucbhelper::Content & parent, rtl::OUString const & title,
     234             :     ucbhelper::Content & result, bool exclusive)
     235             : {
     236          14 :     bool exists = false;
     237             :     try {
     238             :         css::uno::Sequence<css::ucb::ContentInfo> info(
     239          14 :             parent.queryCreatableContentsInfo());
     240          28 :         for (sal_Int32 i = 0; i < info.getLength(); ++i) {
     241             :             // Simply look for the first KIND_FOLDER:
     242          28 :             if ((info[i].Attributes
     243             :                  & css::ucb::ContentInfoAttribute::KIND_FOLDER)
     244             :                 != 0)
     245             :             {
     246             :                 // Make sure the only required bootstrap property is "Title":
     247          14 :                 if ( info[i].Properties.getLength() != 1 || info[i].Properties[0].Name != "Title" )
     248             :                 {
     249           0 :                     continue;
     250             :                 }
     251          14 :                 css::uno::Sequence<rtl::OUString> keys(1);
     252          14 :                 keys[0] = rtl::OUString("Title");
     253          14 :                 css::uno::Sequence<css::uno::Any> values(1);
     254          14 :                 values[0] <<= title;
     255          14 :                 if (parent.insertNewContent(info[i].Type, keys, values, result))
     256             :                 {
     257           6 :                     return true;
     258          14 :                 }
     259             :             }
     260          14 :         }
     261           0 :     } catch (css::ucb::InteractiveIOException const & e) {
     262           0 :         if (e.Code == css::ucb::IOErrorCode_ALREADY_EXISTING) {
     263           0 :             exists = true;
     264             :         } else {
     265             :             SAL_INFO(
     266             :                 "unotools",
     267             :                 "UCBContentHelper::MakeFolder(" << title
     268             :                     << ") InteractiveIOException \"" << e.Message
     269             :                     << "\", code " << +e.Code);
     270             :         }
     271          16 :     } catch (css::ucb::NameClashException const &) {
     272           8 :         exists = true;
     273           0 :     } catch (css::uno::RuntimeException const &) {
     274           0 :         throw;
     275           0 :     } catch (css::ucb::CommandAbortedException const &) {
     276             :         assert(false); // this cannot happen
     277           0 :         throw;
     278           0 :     } catch (css::uno::Exception const &) {
     279           0 :         css::uno::Any e(cppu::getCaughtException());
     280             :         SAL_INFO(
     281             :             "unotools",
     282             :             "UCBContentHelper::MakeFolder(" << title << ") "
     283             :                 << e.getValueType().getTypeName() << " \""
     284           0 :                 << e.get<css::uno::Exception>().Message << '"');
     285             :     }
     286           8 :     if (exists && !exclusive) {
     287           8 :         INetURLObject o(parent.getURL());
     288           8 :         o.Append(title);
     289           8 :         result = content(o);
     290           8 :         return true;
     291             :     } else {
     292           0 :         return false;
     293             :     }
     294             : }
     295             : 
     296           0 : sal_Int64 utl::UCBContentHelper::GetSize(rtl::OUString const & url) {
     297             :     try {
     298           0 :         sal_Int64 n = 0;
     299           0 :         bool ok = (content(url).getPropertyValue(rtl::OUString("Size")) >>= n);
     300             :         SAL_INFO_IF(
     301             :             !ok, "unotools",
     302             :             "UCBContentHelper::GetSize(" << url
     303             :                 << "): Size cannot be determined");
     304           0 :         return n;
     305           0 :     } catch (css::uno::RuntimeException const &) {
     306           0 :         throw;
     307           0 :     } catch (css::ucb::CommandAbortedException const &) {
     308             :         assert(false); // this cannot happen
     309           0 :         throw;
     310           0 :     } catch (css::uno::Exception const &) {
     311           0 :         css::uno::Any e(cppu::getCaughtException());
     312             :         SAL_INFO(
     313             :             "unotools",
     314             :             "UCBContentHelper::GetSize(" << url << ") "
     315             :                 << e.getValueType().getTypeName() << " \""
     316             :                 << e.get<css::uno::Exception>().Message << '"');
     317           0 :         return 0;
     318             :     }
     319             : }
     320             : 
     321           0 : bool utl::UCBContentHelper::IsYounger(
     322             :     rtl::OUString const & younger, rtl::OUString const & older)
     323             : {
     324             :     try {
     325             :         return
     326             :             convert(
     327             :                 content(younger).getPropertyValue(
     328             :                     rtl::OUString("DateModified")).
     329           0 :                 get<css::util::DateTime>())
     330             :             > convert(
     331             :                 content(older).getPropertyValue(
     332             :                     rtl::OUString("DateModified")).
     333           0 :                 get<css::util::DateTime>());
     334           0 :     } catch (css::uno::RuntimeException const &) {
     335           0 :         throw;
     336           0 :     } catch (css::ucb::CommandAbortedException const &) {
     337             :         assert(false); // this cannot happen
     338           0 :         throw;
     339           0 :     } catch (css::uno::Exception const &) {
     340           0 :         css::uno::Any e(cppu::getCaughtException());
     341             :         SAL_INFO(
     342             :             "unotools",
     343             :             "UCBContentHelper::IsYounger(" << younger << ", " << older << ") "
     344             :                 << e.getValueType().getTypeName() << " \""
     345             :                 << e.get<css::uno::Exception>().Message << '"');
     346           0 :         return false;
     347             :     }
     348             : }
     349             : 
     350           0 : bool utl::UCBContentHelper::Exists(rtl::OUString const & url) {
     351           0 :     rtl::OUString pathname;
     352           0 :     if (utl::LocalFileHelper::ConvertURLToPhysicalName(url, pathname)) {
     353             :         // Try to create a directory entry for the given URL:
     354           0 :         rtl::OUString url2;
     355           0 :         if (osl::FileBase::getFileURLFromSystemPath(pathname, url2)
     356             :             == osl::FileBase::E_None)
     357             :         {
     358             :             // #106526 osl_getDirectoryItem is an existence check, no further
     359             :             // osl_getFileStatus call necessary:
     360           0 :             osl::DirectoryItem item;
     361           0 :             return osl::DirectoryItem::get(url2, item) == osl::FileBase::E_None;
     362             :         } else {
     363           0 :             return false;
     364           0 :         }
     365             :     } else {
     366             :         // Divide URL into folder and name part:
     367           0 :         INetURLObject o(url);
     368             :         rtl::OUString name(
     369             :             o.getName(
     370             :                 INetURLObject::LAST_SEGMENT, true,
     371           0 :                 INetURLObject::DECODE_WITH_CHARSET));
     372           0 :         o.removeSegment();
     373           0 :         o.removeFinalSlash();
     374             :         std::vector<rtl::OUString> cs(
     375           0 :             getContents(o.GetMainURL(INetURLObject::NO_DECODE)));
     376           0 :         for (std::vector<rtl::OUString>::iterator i(cs.begin()); i != cs.end();
     377             :              ++i)
     378             :         {
     379           0 :             if (INetURLObject(*i).getName(
     380             :                     INetURLObject::LAST_SEGMENT, true,
     381             :                     INetURLObject::DECODE_WITH_CHARSET).
     382           0 :                 equalsIgnoreAsciiCase(name))
     383             :             {
     384           0 :                 return true;
     385             :             }
     386             :         }
     387           0 :         return false;
     388           0 :     }
     389             : }
     390             : 
     391           0 : bool utl::UCBContentHelper::IsSubPath(
     392             :     rtl::OUString const & parent, rtl::OUString const & child)
     393             : {
     394             :     // The comparison is done in the following way:
     395             :     // - First, compare case sensitively
     396             :     // - If names are different, try a fallback comparing case insensitively
     397             :     // - If the last comparison succeeded, get case preserving normalized names
     398             :     //   for the files and compare them
     399             :     // (The second step is required because retrieving the normalized names
     400             :     // might be very expensive in some cases.)
     401           0 :     INetURLObject candidate(child);
     402           0 :     INetURLObject folder(parent);
     403           0 :     if (candidate.GetProtocol() != folder.GetProtocol()) {
     404           0 :         return false;
     405             :     }
     406           0 :     INetURLObject candidateLower(child.toAsciiLowerCase());
     407           0 :     INetURLObject folderLower(parent.toAsciiLowerCase());
     408             :     try {
     409           0 :         INetURLObject tmp;
     410           0 :         do {
     411           0 :             if (candidate == folder
     412           0 :                 || (candidate.GetProtocol() == INET_PROT_FILE
     413           0 :                     && candidateLower == folderLower
     414             :                     && (getCasePreservingUrl(candidate)
     415           0 :                         == getCasePreservingUrl(folder))))
     416             :             {
     417           0 :                 return true;
     418             :             }
     419           0 :             tmp = candidate;
     420           0 :         } while (candidate.removeSegment() && candidateLower.removeSegment()
     421           0 :                  && candidate != tmp);
     422             :             // INetURLObject::removeSegment sometimes returns true without
     423             :             // modifying the URL, e.g., in case of "file:///"
     424           0 :     } catch (css::uno::RuntimeException const &) {
     425           0 :         throw;
     426           0 :     } catch (css::ucb::CommandAbortedException const &) {
     427             :         assert(false); // this cannot happen
     428           0 :         throw;
     429           0 :     } catch (css::uno::Exception const &) {
     430           0 :         css::uno::Any e(cppu::getCaughtException());
     431             :         SAL_INFO(
     432             :             "unotools",
     433             :             "UCBContentHelper::IsSubPath(" << parent << ", " << child << ") "
     434             :                 << e.getValueType().getTypeName() << " \""
     435           0 :                 << e.get<css::uno::Exception>().Message << '"');
     436             :     }
     437           0 :     return false;
     438             : }
     439             : 
     440        4711 : bool utl::UCBContentHelper::EqualURLs(
     441             :     rtl::OUString const & url1, rtl::OUString const & url2)
     442             : {
     443        4711 :     if (url1.isEmpty() || url2.isEmpty()) {
     444           6 :         return false;
     445             :     }
     446             :     css::uno::Reference< css::ucb::XUniversalContentBroker > ucb(
     447             :         css::ucb::UniversalContentBroker::create(
     448        4705 :             comphelper::getProcessComponentContext()));
     449             :     return
     450        4705 :         ucb->compareContentIds(
     451        9410 :             ucb->createContentIdentifier(canonic(url1)),
     452       18820 :             ucb->createContentIdentifier(canonic(url2)))
     453        9410 :         == 0;
     454             : }
     455             : 
     456             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10