1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "precompiled_sfx2.hxx" 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include <sfx2/DocumentMetadataAccess.hxx> 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> 33*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 34*cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/embed/XStorage.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/embed/XTransactedObject.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/task/ErrorCodeIOException.hpp> 38*cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> 39*cdf0e10cSrcweir #include <com/sun/star/rdf/FileFormat.hpp> 40*cdf0e10cSrcweir #include <com/sun/star/rdf/URIs.hpp> 41*cdf0e10cSrcweir #include <com/sun/star/rdf/Statement.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/rdf/Literal.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/rdf/URI.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/rdf/Repository.hpp> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir #include <rtl/uuid.h> 47*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 48*cdf0e10cSrcweir #include <rtl/uri.hxx> 49*cdf0e10cSrcweir #include <rtl/bootstrap.hxx> 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir #include <comphelper/interaction.hxx> 52*cdf0e10cSrcweir #include <comphelper/makesequence.hxx> 53*cdf0e10cSrcweir #include <comphelper/mediadescriptor.hxx> 54*cdf0e10cSrcweir #include <comphelper/sequenceasvector.hxx> 55*cdf0e10cSrcweir #include <comphelper/storagehelper.hxx> 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir #include <sfx2/docfile.hxx> 58*cdf0e10cSrcweir #include <sfx2/XmlIdRegistry.hxx> 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir #include <libxml/tree.h> // for xmlValidateNCName 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir #include <boost/bind.hpp> 63*cdf0e10cSrcweir #include <boost/shared_array.hpp> 64*cdf0e10cSrcweir #include <boost/tuple/tuple.hpp> 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir #include <vector> 67*cdf0e10cSrcweir #include <set> 68*cdf0e10cSrcweir #include <map> 69*cdf0e10cSrcweir #include <functional> 70*cdf0e10cSrcweir #include <algorithm> 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir #include <unotools/ucbhelper.hxx> 73*cdf0e10cSrcweir #include <com/sun/star/uri/XUriReference.hpp> 74*cdf0e10cSrcweir #include <com/sun/star/uri/XUriReferenceFactory.hpp> 75*cdf0e10cSrcweir #include <com/sun/star/uri/XVndSunStarPkgUrlReferenceFactory.hpp> 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir /* 79*cdf0e10cSrcweir Note: in the context of this implementation, all rdf.QueryExceptions and 80*cdf0e10cSrcweir rdf.RepositoryExceptions are RuntimeExceptions, and will be reported as such. 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir This implementation assumes that it is only used with ODF documents, not mere 83*cdf0e10cSrcweir ODF packages. In other words, we enforce that metadata files must not be 84*cdf0e10cSrcweir called reserved names. 85*cdf0e10cSrcweir */ 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir using namespace ::com::sun::star; 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir namespace sfx2 { 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir bool isValidNCName(::rtl::OUString const & i_rIdref) 93*cdf0e10cSrcweir { 94*cdf0e10cSrcweir const ::rtl::OString id( 95*cdf0e10cSrcweir ::rtl::OUStringToOString(i_rIdref, RTL_TEXTENCODING_UTF8) ); 96*cdf0e10cSrcweir return !(xmlValidateNCName( 97*cdf0e10cSrcweir reinterpret_cast<const unsigned char*>(id.getStr()), 0)); 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////// 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir static const char s_content [] = "content.xml"; 103*cdf0e10cSrcweir static const char s_styles [] = "styles.xml"; 104*cdf0e10cSrcweir static const char s_meta [] = "meta.xml"; 105*cdf0e10cSrcweir static const char s_settings[] = "settings.xml"; 106*cdf0e10cSrcweir static const char s_manifest[] = "manifest.rdf"; 107*cdf0e10cSrcweir static const char s_rdfxml [] = "application/rdf+xml"; 108*cdf0e10cSrcweir static const char s_odfmime [] = "application/vnd.oasis.opendocument."; 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////// 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir static bool isContentFile(::rtl::OUString const & i_rPath) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir return i_rPath.equalsAscii(s_content); 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir static bool isStylesFile (::rtl::OUString const & i_rPath) 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir return i_rPath.equalsAscii(s_styles); 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir static bool isReservedFile(::rtl::OUString const & i_rPath) 123*cdf0e10cSrcweir { 124*cdf0e10cSrcweir return isContentFile(i_rPath) 125*cdf0e10cSrcweir || isStylesFile(i_rPath) 126*cdf0e10cSrcweir || i_rPath.equalsAscii(s_meta) 127*cdf0e10cSrcweir || i_rPath.equalsAscii(s_settings); 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////// 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir uno::Reference<rdf::XURI> createBaseURI( 133*cdf0e10cSrcweir uno::Reference<uno::XComponentContext> const & i_xContext, 134*cdf0e10cSrcweir uno::Reference<embed::XStorage> const & i_xStorage, 135*cdf0e10cSrcweir ::rtl::OUString const & i_rPkgURI, ::rtl::OUString const & i_rSubDocument) 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir if (!i_xContext.is() || !i_xStorage.is() || !i_rPkgURI.getLength()) { 138*cdf0e10cSrcweir throw uno::RuntimeException(); 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir // #i108078# workaround non-hierarchical vnd.sun.star.expand URIs 142*cdf0e10cSrcweir // this really should be done somewhere else, not here. 143*cdf0e10cSrcweir ::rtl::OUString pkgURI(i_rPkgURI); 144*cdf0e10cSrcweir if (pkgURI.matchIgnoreAsciiCaseAsciiL( 145*cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:"))) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir // expand it here (makeAbsolute requires hierarchical URI) 148*cdf0e10cSrcweir pkgURI = pkgURI.copy( RTL_CONSTASCII_LENGTH("vnd.sun.star.expand:") ); 149*cdf0e10cSrcweir if (pkgURI.getLength() != 0) { 150*cdf0e10cSrcweir pkgURI = ::rtl::Uri::decode( 151*cdf0e10cSrcweir pkgURI, rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8); 152*cdf0e10cSrcweir if (pkgURI.getLength() == 0) { 153*cdf0e10cSrcweir throw uno::RuntimeException(); 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir ::rtl::Bootstrap::expandMacros(pkgURI); 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir const uno::Reference<lang::XMultiComponentFactory> xServiceFactory( 160*cdf0e10cSrcweir i_xContext->getServiceManager(), uno::UNO_SET_THROW); 161*cdf0e10cSrcweir const uno::Reference<uri::XUriReferenceFactory> xUriFactory( 162*cdf0e10cSrcweir xServiceFactory->createInstanceWithContext( 163*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 164*cdf0e10cSrcweir "com.sun.star.uri.UriReferenceFactory"), i_xContext), 165*cdf0e10cSrcweir uno::UNO_QUERY_THROW); 166*cdf0e10cSrcweir uno::Reference< uri::XUriReference > xBaseURI; 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir const uno::Reference< uri::XUriReference > xPkgURI( 169*cdf0e10cSrcweir xUriFactory->parse(pkgURI), uno::UNO_SET_THROW ); 170*cdf0e10cSrcweir xPkgURI->clearFragment(); 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir // need to know whether the storage is a FileSystemStorage 173*cdf0e10cSrcweir // XServiceInfo would be better, but it is not implemented 174*cdf0e10cSrcweir // if ( pkgURI.getLength() && ::utl::UCBContentHelper::IsFolder(pkgURI) ) 175*cdf0e10cSrcweir if (true) { 176*cdf0e10cSrcweir xBaseURI.set( xPkgURI, uno::UNO_SET_THROW ); 177*cdf0e10cSrcweir #if 0 178*cdf0e10cSrcweir } else { 179*cdf0e10cSrcweir const uno::Reference<uri::XVndSunStarPkgUrlReferenceFactory> 180*cdf0e10cSrcweir xPkgUriFactory( xServiceFactory->createInstanceWithContext( 181*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 182*cdf0e10cSrcweir "com.sun.star.uri.VndSunStarPkgUrlReferenceFactory"), 183*cdf0e10cSrcweir i_xContext), 184*cdf0e10cSrcweir uno::UNO_QUERY_THROW); 185*cdf0e10cSrcweir xBaseURI.set( xPkgUriFactory->createVndSunStarPkgUrlReference(xPkgURI), 186*cdf0e10cSrcweir uno::UNO_SET_THROW ); 187*cdf0e10cSrcweir #endif 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir ::rtl::OUStringBuffer buf; 190*cdf0e10cSrcweir if (!xBaseURI->getUriReference().endsWithAsciiL("/", 1)) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir const sal_Int32 count( xBaseURI->getPathSegmentCount() ); 193*cdf0e10cSrcweir if (count > 0) 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir const ::rtl::OUString last( xBaseURI->getPathSegment(count - 1) ); 196*cdf0e10cSrcweir buf.append(last); 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir buf.append(static_cast<sal_Unicode>('/')); 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir if (i_rSubDocument.getLength()) 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir buf.append(i_rSubDocument); 203*cdf0e10cSrcweir buf.append(static_cast<sal_Unicode>('/')); 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir const ::rtl::OUString Path(buf.makeStringAndClear()); 206*cdf0e10cSrcweir if (Path.getLength()) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir const uno::Reference< uri::XUriReference > xPathURI( 209*cdf0e10cSrcweir xUriFactory->parse(Path), uno::UNO_SET_THROW ); 210*cdf0e10cSrcweir xBaseURI.set( 211*cdf0e10cSrcweir xUriFactory->makeAbsolute(xBaseURI, xPathURI, 212*cdf0e10cSrcweir true, uri::RelativeUriExcessParentSegments_ERROR), 213*cdf0e10cSrcweir uno::UNO_SET_THROW); 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir return rdf::URI::create(i_xContext, xBaseURI->getUriReference()); 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////// 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir struct DocumentMetadataAccess_Impl 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir // note: these are all initialized in constructor, and loadFromStorage 224*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext> m_xContext; 225*cdf0e10cSrcweir const IXmlIdRegistrySupplier & m_rXmlIdRegistrySupplier; 226*cdf0e10cSrcweir uno::Reference<rdf::XURI> m_xBaseURI; 227*cdf0e10cSrcweir uno::Reference<rdf::XRepository> m_xRepository; 228*cdf0e10cSrcweir uno::Reference<rdf::XNamedGraph> m_xManifest; 229*cdf0e10cSrcweir DocumentMetadataAccess_Impl( 230*cdf0e10cSrcweir uno::Reference<uno::XComponentContext> const& i_xContext, 231*cdf0e10cSrcweir IXmlIdRegistrySupplier const & i_rRegistrySupplier) 232*cdf0e10cSrcweir : m_xContext(i_xContext) 233*cdf0e10cSrcweir , m_rXmlIdRegistrySupplier(i_rRegistrySupplier) 234*cdf0e10cSrcweir , m_xBaseURI() 235*cdf0e10cSrcweir , m_xRepository() 236*cdf0e10cSrcweir , m_xManifest() 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir OSL_ENSURE(m_xContext.is(), "context null"); 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir }; 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir // this is... a hack. 243*cdf0e10cSrcweir template<sal_Int16 Constant> 244*cdf0e10cSrcweir /*static*/ uno::Reference<rdf::XURI> 245*cdf0e10cSrcweir getURI(uno::Reference< uno::XComponentContext > const & i_xContext) 246*cdf0e10cSrcweir { 247*cdf0e10cSrcweir static uno::Reference< rdf::XURI > xURI( 248*cdf0e10cSrcweir rdf::URI::createKnown(i_xContext, Constant), uno::UNO_QUERY_THROW); 249*cdf0e10cSrcweir return xURI; 250*cdf0e10cSrcweir } 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir /** would storing the file to a XStorage succeed? */ 254*cdf0e10cSrcweir static bool isFileNameValid(const ::rtl::OUString & i_rFileName) 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir if (i_rFileName.getLength() <= 0) return false; 257*cdf0e10cSrcweir if (i_rFileName[0] == '/') return false; // no absolute paths! 258*cdf0e10cSrcweir sal_Int32 idx(0); 259*cdf0e10cSrcweir do { 260*cdf0e10cSrcweir const ::rtl::OUString segment( 261*cdf0e10cSrcweir i_rFileName.getToken(0, static_cast<sal_Unicode> ('/'), idx) ); 262*cdf0e10cSrcweir if (!segment.getLength() || // no empty segments 263*cdf0e10cSrcweir segment.equalsAscii(".") || // no . segments 264*cdf0e10cSrcweir segment.equalsAscii("..") || // no .. segments 265*cdf0e10cSrcweir !::comphelper::OStorageHelper::IsValidZipEntryFileName( 266*cdf0e10cSrcweir segment, sal_False)) // no invalid characters 267*cdf0e10cSrcweir return false; 268*cdf0e10cSrcweir } while (idx >= 0); 269*cdf0e10cSrcweir return true; 270*cdf0e10cSrcweir } 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir /** split a uri hierarchy into first segment and rest */ 273*cdf0e10cSrcweir static bool 274*cdf0e10cSrcweir splitPath(::rtl::OUString const & i_rPath, 275*cdf0e10cSrcweir ::rtl::OUString & o_rDir, ::rtl::OUString& o_rRest) 276*cdf0e10cSrcweir { 277*cdf0e10cSrcweir const sal_Int32 idx(i_rPath.indexOf(static_cast<sal_Unicode>('/'))); 278*cdf0e10cSrcweir if (idx < 0 || idx >= i_rPath.getLength()) { 279*cdf0e10cSrcweir o_rDir = ::rtl::OUString(); 280*cdf0e10cSrcweir o_rRest = i_rPath; 281*cdf0e10cSrcweir return true; 282*cdf0e10cSrcweir } else if (idx == 0 || idx == i_rPath.getLength() - 1) { 283*cdf0e10cSrcweir // input must not start or end with '/' 284*cdf0e10cSrcweir return false; 285*cdf0e10cSrcweir } else { 286*cdf0e10cSrcweir o_rDir = (i_rPath.copy(0, idx)); 287*cdf0e10cSrcweir o_rRest = (i_rPath.copy(idx+1)); 288*cdf0e10cSrcweir return true; 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir static bool 293*cdf0e10cSrcweir splitXmlId(::rtl::OUString const & i_XmlId, 294*cdf0e10cSrcweir ::rtl::OUString & o_StreamName, ::rtl::OUString& o_Idref ) 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir const sal_Int32 idx(i_XmlId.indexOf(static_cast<sal_Unicode>('#'))); 297*cdf0e10cSrcweir if ((idx <= 0) || (idx >= i_XmlId.getLength() - 1)) { 298*cdf0e10cSrcweir return false; 299*cdf0e10cSrcweir } else { 300*cdf0e10cSrcweir o_StreamName = (i_XmlId.copy(0, idx)); 301*cdf0e10cSrcweir o_Idref = (i_XmlId.copy(idx+1)); 302*cdf0e10cSrcweir return isValidXmlId(o_StreamName, o_Idref); 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////// 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir static uno::Reference<rdf::XURI> 309*cdf0e10cSrcweir getURIForStream(struct DocumentMetadataAccess_Impl& i_rImpl, 310*cdf0e10cSrcweir ::rtl::OUString const& i_rPath) 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xURI( 313*cdf0e10cSrcweir rdf::URI::createNS( i_rImpl.m_xContext, 314*cdf0e10cSrcweir i_rImpl.m_xBaseURI->getStringValue(), i_rPath), 315*cdf0e10cSrcweir uno::UNO_SET_THROW); 316*cdf0e10cSrcweir return xURI; 317*cdf0e10cSrcweir } 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir /** add statements declaring i_xResource to be a file of type i_xType with 320*cdf0e10cSrcweir path i_rPath to manifest, with optional additional types i_pTypes */ 321*cdf0e10cSrcweir static void 322*cdf0e10cSrcweir addFile(struct DocumentMetadataAccess_Impl & i_rImpl, 323*cdf0e10cSrcweir uno::Reference<rdf::XURI> const& i_xType, 324*cdf0e10cSrcweir ::rtl::OUString const & i_rPath, 325*cdf0e10cSrcweir const uno::Sequence < uno::Reference< rdf::XURI > > * i_pTypes = 0) 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir try { 328*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xURI( getURIForStream( 329*cdf0e10cSrcweir i_rImpl, i_rPath) ); 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir i_rImpl.m_xManifest->addStatement(i_rImpl.m_xBaseURI.get(), 332*cdf0e10cSrcweir getURI<rdf::URIs::PKG_HASPART>(i_rImpl.m_xContext), 333*cdf0e10cSrcweir xURI.get()); 334*cdf0e10cSrcweir i_rImpl.m_xManifest->addStatement(xURI.get(), 335*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext), 336*cdf0e10cSrcweir i_xType.get()); 337*cdf0e10cSrcweir if (i_pTypes) { 338*cdf0e10cSrcweir for (sal_Int32 i = 0; i < i_pTypes->getLength(); ++i) { 339*cdf0e10cSrcweir i_rImpl.m_xManifest->addStatement(xURI.get(), 340*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext), 341*cdf0e10cSrcweir (*i_pTypes)[i].get()); 342*cdf0e10cSrcweir } 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 345*cdf0e10cSrcweir throw; 346*cdf0e10cSrcweir } catch (uno::Exception & e) { 347*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 348*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 349*cdf0e10cSrcweir "addFile: exception"), /*this*/0, uno::makeAny(e)); 350*cdf0e10cSrcweir } 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir /** add content.xml or styles.xml to manifest */ 354*cdf0e10cSrcweir static bool 355*cdf0e10cSrcweir addContentOrStylesFileImpl(struct DocumentMetadataAccess_Impl & i_rImpl, 356*cdf0e10cSrcweir const ::rtl::OUString & i_rPath) 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir uno::Reference<rdf::XURI> xType; 359*cdf0e10cSrcweir if (isContentFile(i_rPath)) { 360*cdf0e10cSrcweir xType.set(getURI<rdf::URIs::ODF_CONTENTFILE>(i_rImpl.m_xContext)); 361*cdf0e10cSrcweir } else if (isStylesFile(i_rPath)) { 362*cdf0e10cSrcweir xType.set(getURI<rdf::URIs::ODF_STYLESFILE>(i_rImpl.m_xContext)); 363*cdf0e10cSrcweir } else { 364*cdf0e10cSrcweir return false; 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir addFile(i_rImpl, xType.get(), i_rPath); 367*cdf0e10cSrcweir return true; 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir /** add metadata file to manifest */ 371*cdf0e10cSrcweir static void 372*cdf0e10cSrcweir addMetadataFileImpl(struct DocumentMetadataAccess_Impl & i_rImpl, 373*cdf0e10cSrcweir const ::rtl::OUString & i_rPath, 374*cdf0e10cSrcweir const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes) 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir addFile(i_rImpl, 377*cdf0e10cSrcweir getURI<rdf::URIs::PKG_METADATAFILE>(i_rImpl.m_xContext), 378*cdf0e10cSrcweir i_rPath, &i_rTypes); 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir /** remove a file from the manifest */ 382*cdf0e10cSrcweir static void 383*cdf0e10cSrcweir removeFile(struct DocumentMetadataAccess_Impl & i_rImpl, 384*cdf0e10cSrcweir uno::Reference<rdf::XURI> const& i_xPart) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir if (!i_xPart.is()) throw uno::RuntimeException(); 387*cdf0e10cSrcweir try { 388*cdf0e10cSrcweir i_rImpl.m_xManifest->removeStatements(i_rImpl.m_xBaseURI.get(), 389*cdf0e10cSrcweir getURI<rdf::URIs::PKG_HASPART>(i_rImpl.m_xContext), 390*cdf0e10cSrcweir i_xPart.get()); 391*cdf0e10cSrcweir i_rImpl.m_xManifest->removeStatements(i_xPart.get(), 392*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext), 0); 393*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 394*cdf0e10cSrcweir throw; 395*cdf0e10cSrcweir } catch (uno::Exception & e) { 396*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 397*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("removeFile: exception"), 398*cdf0e10cSrcweir 0, uno::makeAny(e)); 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir } 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir static ::std::vector< uno::Reference< rdf::XURI > > 403*cdf0e10cSrcweir getAllParts(struct DocumentMetadataAccess_Impl & i_rImpl) 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir ::std::vector< uno::Reference< rdf::XURI > > ret; 406*cdf0e10cSrcweir try { 407*cdf0e10cSrcweir const uno::Reference<container::XEnumeration> xEnum( 408*cdf0e10cSrcweir i_rImpl.m_xManifest->getStatements( i_rImpl.m_xBaseURI.get(), 409*cdf0e10cSrcweir getURI<rdf::URIs::PKG_HASPART>(i_rImpl.m_xContext), 0), 410*cdf0e10cSrcweir uno::UNO_SET_THROW); 411*cdf0e10cSrcweir while (xEnum->hasMoreElements()) { 412*cdf0e10cSrcweir rdf::Statement stmt; 413*cdf0e10cSrcweir if (!(xEnum->nextElement() >>= stmt)) { 414*cdf0e10cSrcweir throw uno::RuntimeException(); 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xPart(stmt.Object, 417*cdf0e10cSrcweir uno::UNO_QUERY); 418*cdf0e10cSrcweir if (!xPart.is()) continue; 419*cdf0e10cSrcweir ret.push_back(xPart); 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir return ret; 422*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 423*cdf0e10cSrcweir throw; 424*cdf0e10cSrcweir } catch (uno::Exception & e) { 425*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 426*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("getAllParts: exception"), 427*cdf0e10cSrcweir 0, uno::makeAny(e)); 428*cdf0e10cSrcweir } 429*cdf0e10cSrcweir } 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir static bool 432*cdf0e10cSrcweir isPartOfType(struct DocumentMetadataAccess_Impl & i_rImpl, 433*cdf0e10cSrcweir uno::Reference<rdf::XURI> const & i_xPart, 434*cdf0e10cSrcweir uno::Reference<rdf::XURI> const & i_xType) 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir if (!i_xPart.is() || !i_xType.is()) throw uno::RuntimeException(); 437*cdf0e10cSrcweir try { 438*cdf0e10cSrcweir const uno::Reference<container::XEnumeration> xEnum( 439*cdf0e10cSrcweir i_rImpl.m_xManifest->getStatements(i_xPart.get(), 440*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext), 441*cdf0e10cSrcweir i_xType.get()), 442*cdf0e10cSrcweir uno::UNO_SET_THROW); 443*cdf0e10cSrcweir return (xEnum->hasMoreElements()); 444*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 445*cdf0e10cSrcweir throw; 446*cdf0e10cSrcweir } catch (uno::Exception & e) { 447*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 448*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("isPartOfType: exception"), 449*cdf0e10cSrcweir 0, uno::makeAny(e)); 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////// 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir static ucb::InteractiveAugmentedIOException 456*cdf0e10cSrcweir mkException( ::rtl::OUString const & i_rMessage, 457*cdf0e10cSrcweir ucb::IOErrorCode const i_ErrorCode, 458*cdf0e10cSrcweir ::rtl::OUString const & i_rUri, ::rtl::OUString const & i_rResource) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir ucb::InteractiveAugmentedIOException iaioe; 461*cdf0e10cSrcweir iaioe.Message = i_rMessage; 462*cdf0e10cSrcweir iaioe.Classification = task::InteractionClassification_ERROR; 463*cdf0e10cSrcweir iaioe.Code = i_ErrorCode; 464*cdf0e10cSrcweir 465*cdf0e10cSrcweir const beans::PropertyValue uriProp(::rtl::OUString::createFromAscii("Uri"), 466*cdf0e10cSrcweir -1, uno::makeAny(i_rUri), static_cast<beans::PropertyState>(0)); 467*cdf0e10cSrcweir const beans::PropertyValue rnProp( 468*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("ResourceName"), 469*cdf0e10cSrcweir -1, uno::makeAny(i_rResource), static_cast<beans::PropertyState>(0)); 470*cdf0e10cSrcweir iaioe.Arguments = ::comphelper::makeSequence( 471*cdf0e10cSrcweir uno::makeAny(uriProp), uno::makeAny(rnProp)); 472*cdf0e10cSrcweir return iaioe; 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir /** error handling policy. 476*cdf0e10cSrcweir <p>If a handler is given, ask it how to proceed: 477*cdf0e10cSrcweir <ul><li>(default:) cancel import, raise exception</li> 478*cdf0e10cSrcweir <li>ignore the error and continue</li> 479*cdf0e10cSrcweir <li>retry the action that led to the error</li></ul></p> 480*cdf0e10cSrcweir N.B.: must not be called before DMA is fully initalized! 481*cdf0e10cSrcweir @returns true iff caller should retry 482*cdf0e10cSrcweir */ 483*cdf0e10cSrcweir static bool 484*cdf0e10cSrcweir handleError( ucb::InteractiveAugmentedIOException const & i_rException, 485*cdf0e10cSrcweir const uno::Reference<task::XInteractionHandler> & i_xHandler) 486*cdf0e10cSrcweir { 487*cdf0e10cSrcweir if (!i_xHandler.is()) { 488*cdf0e10cSrcweir throw lang::WrappedTargetException(::rtl::OUString::createFromAscii( 489*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromStorage: exception"), 490*cdf0e10cSrcweir /* *this*/ 0, uno::makeAny(i_rException)); 491*cdf0e10cSrcweir } 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest( 494*cdf0e10cSrcweir new ::comphelper::OInteractionRequest(uno::makeAny(i_rException)) ); 495*cdf0e10cSrcweir ::rtl::Reference< ::comphelper::OInteractionRetry > pRetry( 496*cdf0e10cSrcweir new ::comphelper::OInteractionRetry ); 497*cdf0e10cSrcweir ::rtl::Reference< ::comphelper::OInteractionApprove > pApprove( 498*cdf0e10cSrcweir new ::comphelper::OInteractionApprove ); 499*cdf0e10cSrcweir ::rtl::Reference< ::comphelper::OInteractionAbort > pAbort( 500*cdf0e10cSrcweir new ::comphelper::OInteractionAbort ); 501*cdf0e10cSrcweir /* this does not seem to work 502*cdf0e10cSrcweir if (i_rException.Code != ucb::IOErrorCode_WRONG_FORMAT) { 503*cdf0e10cSrcweir pRequest->addContinuation( pRetry.get() ); 504*cdf0e10cSrcweir } 505*cdf0e10cSrcweir */ 506*cdf0e10cSrcweir pRequest->addContinuation( pApprove.get() ); 507*cdf0e10cSrcweir pRequest->addContinuation( pAbort.get() ); 508*cdf0e10cSrcweir // actually call the handler 509*cdf0e10cSrcweir i_xHandler->handle( pRequest.get() ); 510*cdf0e10cSrcweir if (pRetry->wasSelected()) { 511*cdf0e10cSrcweir return true; 512*cdf0e10cSrcweir } else if (pApprove->wasSelected()) { 513*cdf0e10cSrcweir return false; 514*cdf0e10cSrcweir } else { 515*cdf0e10cSrcweir OSL_ENSURE(pAbort->wasSelected(), "no continuation selected?"); 516*cdf0e10cSrcweir throw lang::WrappedTargetException(::rtl::OUString::createFromAscii( 517*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromStorage: exception"), 518*cdf0e10cSrcweir /* *this*/ 0, uno::makeAny(i_rException)); 519*cdf0e10cSrcweir } 520*cdf0e10cSrcweir } 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir /** check if storage has content.xml/styles.xml; 523*cdf0e10cSrcweir e.g. ODB files seem to only have content.xml */ 524*cdf0e10cSrcweir static void 525*cdf0e10cSrcweir collectFilesFromStorage(uno::Reference<embed::XStorage> const& i_xStorage, 526*cdf0e10cSrcweir ::rtl::OUString i_Path, 527*cdf0e10cSrcweir std::set< ::rtl::OUString > & o_rFiles) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir static ::rtl::OUString content(::rtl::OUString::createFromAscii(s_content)); 530*cdf0e10cSrcweir static ::rtl::OUString styles (::rtl::OUString::createFromAscii(s_styles )); 531*cdf0e10cSrcweir try { 532*cdf0e10cSrcweir if (i_xStorage->hasByName(content) && 533*cdf0e10cSrcweir i_xStorage->isStreamElement(content)) 534*cdf0e10cSrcweir { 535*cdf0e10cSrcweir o_rFiles.insert(i_Path + content); 536*cdf0e10cSrcweir } 537*cdf0e10cSrcweir if (i_xStorage->hasByName(styles) && 538*cdf0e10cSrcweir i_xStorage->isStreamElement(styles)) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir o_rFiles.insert(i_Path + styles); 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir } catch (uno::Exception &) { 543*cdf0e10cSrcweir OSL_TRACE("collectFilesFromStorage: exception?"); 544*cdf0e10cSrcweir } 545*cdf0e10cSrcweir } 546*cdf0e10cSrcweir 547*cdf0e10cSrcweir /** import a metadata file into repository */ 548*cdf0e10cSrcweir static void 549*cdf0e10cSrcweir readStream(struct DocumentMetadataAccess_Impl & i_rImpl, 550*cdf0e10cSrcweir uno::Reference< embed::XStorage > const & i_xStorage, 551*cdf0e10cSrcweir ::rtl::OUString const & i_rPath, 552*cdf0e10cSrcweir ::rtl::OUString const & i_rBaseURI) 553*cdf0e10cSrcweir { 554*cdf0e10cSrcweir ::rtl::OUString dir; 555*cdf0e10cSrcweir ::rtl::OUString rest; 556*cdf0e10cSrcweir try { 557*cdf0e10cSrcweir if (!splitPath(i_rPath, dir, rest)) throw uno::RuntimeException(); 558*cdf0e10cSrcweir if (dir.equalsAscii("")) { 559*cdf0e10cSrcweir if (i_xStorage->isStreamElement(i_rPath)) { 560*cdf0e10cSrcweir const uno::Reference<io::XStream> xStream( 561*cdf0e10cSrcweir i_xStorage->openStreamElement(i_rPath, 562*cdf0e10cSrcweir embed::ElementModes::READ), uno::UNO_SET_THROW); 563*cdf0e10cSrcweir const uno::Reference<io::XInputStream> xInStream( 564*cdf0e10cSrcweir xStream->getInputStream(), uno::UNO_SET_THROW ); 565*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xBaseURI( 566*cdf0e10cSrcweir rdf::URI::create(i_rImpl.m_xContext, i_rBaseURI)); 567*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xURI( 568*cdf0e10cSrcweir rdf::URI::createNS(i_rImpl.m_xContext, 569*cdf0e10cSrcweir i_rBaseURI, i_rPath)); 570*cdf0e10cSrcweir i_rImpl.m_xRepository->importGraph(rdf::FileFormat::RDF_XML, 571*cdf0e10cSrcweir xInStream, xURI, xBaseURI); 572*cdf0e10cSrcweir } else { 573*cdf0e10cSrcweir throw mkException(::rtl::OUString::createFromAscii( 574*cdf0e10cSrcweir "readStream: is not a stream"), 575*cdf0e10cSrcweir ucb::IOErrorCode_NO_FILE, i_rBaseURI + i_rPath, i_rPath); 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir } else { 578*cdf0e10cSrcweir if (i_xStorage->isStorageElement(dir)) { 579*cdf0e10cSrcweir const uno::Reference<embed::XStorage> xDir( 580*cdf0e10cSrcweir i_xStorage->openStorageElement(dir, 581*cdf0e10cSrcweir embed::ElementModes::READ)); 582*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet > xDirProps(xDir, 583*cdf0e10cSrcweir uno::UNO_QUERY_THROW); 584*cdf0e10cSrcweir try { 585*cdf0e10cSrcweir ::rtl::OUString mimeType; 586*cdf0e10cSrcweir xDirProps->getPropertyValue( 587*cdf0e10cSrcweir ::comphelper::MediaDescriptor::PROP_MEDIATYPE() ) 588*cdf0e10cSrcweir >>= mimeType; 589*cdf0e10cSrcweir if (mimeType.matchAsciiL(s_odfmime, sizeof(s_odfmime) - 1)) 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir OSL_TRACE("readStream: " 592*cdf0e10cSrcweir "refusing to recurse into embedded document"); 593*cdf0e10cSrcweir return; 594*cdf0e10cSrcweir } 595*cdf0e10cSrcweir } catch (uno::Exception &) { } 596*cdf0e10cSrcweir ::rtl::OUStringBuffer buf(i_rBaseURI); 597*cdf0e10cSrcweir buf.append(dir).append(static_cast<sal_Unicode>('/')); 598*cdf0e10cSrcweir readStream(i_rImpl, xDir, rest, buf.makeStringAndClear() ); 599*cdf0e10cSrcweir } else { 600*cdf0e10cSrcweir throw mkException(::rtl::OUString::createFromAscii( 601*cdf0e10cSrcweir "readStream: is not a directory"), 602*cdf0e10cSrcweir ucb::IOErrorCode_NO_DIRECTORY, i_rBaseURI + dir, dir); 603*cdf0e10cSrcweir } 604*cdf0e10cSrcweir } 605*cdf0e10cSrcweir } catch (container::NoSuchElementException & e) { 606*cdf0e10cSrcweir throw mkException(e.Message, ucb::IOErrorCode_NOT_EXISTING_PATH, 607*cdf0e10cSrcweir i_rBaseURI + i_rPath, i_rPath); 608*cdf0e10cSrcweir } catch (io::IOException & e) { 609*cdf0e10cSrcweir throw mkException(e.Message, ucb::IOErrorCode_CANT_READ, 610*cdf0e10cSrcweir i_rBaseURI + i_rPath, i_rPath); 611*cdf0e10cSrcweir } catch (rdf::ParseException & e) { 612*cdf0e10cSrcweir throw mkException(e.Message, ucb::IOErrorCode_WRONG_FORMAT, 613*cdf0e10cSrcweir i_rBaseURI + i_rPath, i_rPath); 614*cdf0e10cSrcweir } 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir 617*cdf0e10cSrcweir /** import a metadata file into repository */ 618*cdf0e10cSrcweir static void 619*cdf0e10cSrcweir importFile(struct DocumentMetadataAccess_Impl & i_rImpl, 620*cdf0e10cSrcweir uno::Reference<embed::XStorage> const & i_xStorage, 621*cdf0e10cSrcweir ::rtl::OUString const & i_rBaseURI, 622*cdf0e10cSrcweir uno::Reference<task::XInteractionHandler> const & i_xHandler, 623*cdf0e10cSrcweir ::rtl::OUString i_rPath) 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir retry: 626*cdf0e10cSrcweir try { 627*cdf0e10cSrcweir readStream(i_rImpl, i_xStorage, i_rPath, i_rBaseURI); 628*cdf0e10cSrcweir } catch (ucb::InteractiveAugmentedIOException & e) { 629*cdf0e10cSrcweir if (handleError(e, i_xHandler)) goto retry; 630*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 631*cdf0e10cSrcweir throw; 632*cdf0e10cSrcweir } catch (uno::Exception & e) { 633*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 634*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("importFile: exception"), 635*cdf0e10cSrcweir 0, uno::makeAny(e)); 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir /** actually write a metadata file to the storage */ 640*cdf0e10cSrcweir static void 641*cdf0e10cSrcweir exportStream(struct DocumentMetadataAccess_Impl & i_rImpl, 642*cdf0e10cSrcweir uno::Reference< embed::XStorage > const & i_xStorage, 643*cdf0e10cSrcweir uno::Reference<rdf::XURI> const & i_xGraphName, 644*cdf0e10cSrcweir ::rtl::OUString const & i_rFileName, 645*cdf0e10cSrcweir ::rtl::OUString const & i_rBaseURI) 646*cdf0e10cSrcweir { 647*cdf0e10cSrcweir const uno::Reference<io::XStream> xStream( 648*cdf0e10cSrcweir i_xStorage->openStreamElement(i_rFileName, 649*cdf0e10cSrcweir embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE), 650*cdf0e10cSrcweir uno::UNO_SET_THROW); 651*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet > xStreamProps(xStream, 652*cdf0e10cSrcweir uno::UNO_QUERY); 653*cdf0e10cSrcweir if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage 654*cdf0e10cSrcweir xStreamProps->setPropertyValue( 655*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("MediaType"), 656*cdf0e10cSrcweir uno::makeAny(::rtl::OUString::createFromAscii(s_rdfxml))); 657*cdf0e10cSrcweir } 658*cdf0e10cSrcweir const uno::Reference<io::XOutputStream> xOutStream( 659*cdf0e10cSrcweir xStream->getOutputStream(), uno::UNO_SET_THROW ); 660*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xBaseURI( 661*cdf0e10cSrcweir rdf::URI::create(i_rImpl.m_xContext, i_rBaseURI)); 662*cdf0e10cSrcweir i_rImpl.m_xRepository->exportGraph(rdf::FileFormat::RDF_XML, 663*cdf0e10cSrcweir xOutStream, i_xGraphName, xBaseURI); 664*cdf0e10cSrcweir } 665*cdf0e10cSrcweir 666*cdf0e10cSrcweir /** write a metadata file to the storage */ 667*cdf0e10cSrcweir static void 668*cdf0e10cSrcweir writeStream(struct DocumentMetadataAccess_Impl & i_rImpl, 669*cdf0e10cSrcweir uno::Reference< embed::XStorage > const & i_xStorage, 670*cdf0e10cSrcweir uno::Reference<rdf::XURI> const & i_xGraphName, 671*cdf0e10cSrcweir ::rtl::OUString const & i_rPath, 672*cdf0e10cSrcweir ::rtl::OUString const & i_rBaseURI) 673*cdf0e10cSrcweir { 674*cdf0e10cSrcweir ::rtl::OUString dir; 675*cdf0e10cSrcweir ::rtl::OUString rest; 676*cdf0e10cSrcweir if (!splitPath(i_rPath, dir, rest)) throw uno::RuntimeException(); 677*cdf0e10cSrcweir try { 678*cdf0e10cSrcweir if (dir.equalsAscii("")) { 679*cdf0e10cSrcweir exportStream(i_rImpl, i_xStorage, i_xGraphName, i_rPath, 680*cdf0e10cSrcweir i_rBaseURI); 681*cdf0e10cSrcweir } else { 682*cdf0e10cSrcweir const uno::Reference<embed::XStorage> xDir( 683*cdf0e10cSrcweir i_xStorage->openStorageElement(dir, 684*cdf0e10cSrcweir embed::ElementModes::WRITE)); 685*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet > xDirProps(xDir, 686*cdf0e10cSrcweir uno::UNO_QUERY_THROW); 687*cdf0e10cSrcweir try { 688*cdf0e10cSrcweir ::rtl::OUString mimeType; 689*cdf0e10cSrcweir xDirProps->getPropertyValue( 690*cdf0e10cSrcweir ::comphelper::MediaDescriptor::PROP_MEDIATYPE() ) 691*cdf0e10cSrcweir >>= mimeType; 692*cdf0e10cSrcweir if (mimeType.matchAsciiL(s_odfmime, sizeof(s_odfmime) - 1)) { 693*cdf0e10cSrcweir OSL_TRACE("writeStream: " 694*cdf0e10cSrcweir "refusing to recurse into embedded document"); 695*cdf0e10cSrcweir return; 696*cdf0e10cSrcweir } 697*cdf0e10cSrcweir } catch (uno::Exception &) { } 698*cdf0e10cSrcweir ::rtl::OUStringBuffer buf(i_rBaseURI); 699*cdf0e10cSrcweir buf.append(dir).append(static_cast<sal_Unicode>('/')); 700*cdf0e10cSrcweir writeStream(i_rImpl, xDir, i_xGraphName, rest, 701*cdf0e10cSrcweir buf.makeStringAndClear()); 702*cdf0e10cSrcweir uno::Reference<embed::XTransactedObject> const xTransaction( 703*cdf0e10cSrcweir xDir, uno::UNO_QUERY); 704*cdf0e10cSrcweir if (xTransaction.is()) { 705*cdf0e10cSrcweir xTransaction->commit(); 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir } 708*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 709*cdf0e10cSrcweir throw; 710*cdf0e10cSrcweir } catch (io::IOException &) { 711*cdf0e10cSrcweir throw; 712*cdf0e10cSrcweir } 713*cdf0e10cSrcweir } 714*cdf0e10cSrcweir 715*cdf0e10cSrcweir static void 716*cdf0e10cSrcweir initLoading(struct DocumentMetadataAccess_Impl & i_rImpl, 717*cdf0e10cSrcweir const uno::Reference< embed::XStorage > & i_xStorage, 718*cdf0e10cSrcweir const uno::Reference<rdf::XURI> & i_xBaseURI, 719*cdf0e10cSrcweir const uno::Reference<task::XInteractionHandler> & i_xHandler) 720*cdf0e10cSrcweir { 721*cdf0e10cSrcweir retry: 722*cdf0e10cSrcweir // clear old data 723*cdf0e10cSrcweir i_rImpl.m_xManifest.clear(); 724*cdf0e10cSrcweir // init BaseURI 725*cdf0e10cSrcweir i_rImpl.m_xBaseURI = i_xBaseURI; 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir // create repository 728*cdf0e10cSrcweir i_rImpl.m_xRepository.clear(); 729*cdf0e10cSrcweir i_rImpl.m_xRepository.set(rdf::Repository::create(i_rImpl.m_xContext), 730*cdf0e10cSrcweir uno::UNO_SET_THROW); 731*cdf0e10cSrcweir 732*cdf0e10cSrcweir const ::rtl::OUString manifest ( 733*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(s_manifest)); 734*cdf0e10cSrcweir const ::rtl::OUString baseURI( i_xBaseURI->getStringValue() ); 735*cdf0e10cSrcweir // try to delay raising errors until after initialization is done 736*cdf0e10cSrcweir uno::Any rterr; 737*cdf0e10cSrcweir ucb::InteractiveAugmentedIOException iaioe; 738*cdf0e10cSrcweir bool err(false); 739*cdf0e10cSrcweir 740*cdf0e10cSrcweir const uno::Reference <rdf::XURI> xManifest( 741*cdf0e10cSrcweir getURIForStream(i_rImpl, manifest)); 742*cdf0e10cSrcweir try { 743*cdf0e10cSrcweir readStream(i_rImpl, i_xStorage, manifest, baseURI); 744*cdf0e10cSrcweir } catch (ucb::InteractiveAugmentedIOException & e) { 745*cdf0e10cSrcweir // no manifest.rdf: this is not an error in ODF < 1.2 746*cdf0e10cSrcweir if (!(ucb::IOErrorCode_NOT_EXISTING_PATH == e.Code)) { 747*cdf0e10cSrcweir iaioe = e; 748*cdf0e10cSrcweir err = true; 749*cdf0e10cSrcweir } 750*cdf0e10cSrcweir } catch (uno::Exception & e) { 751*cdf0e10cSrcweir rterr <<= e; 752*cdf0e10cSrcweir } 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir // init manifest graph 755*cdf0e10cSrcweir const uno::Reference<rdf::XNamedGraph> xManifestGraph( 756*cdf0e10cSrcweir i_rImpl.m_xRepository->getGraph(xManifest)); 757*cdf0e10cSrcweir i_rImpl.m_xManifest.set(xManifestGraph.is() ? xManifestGraph : 758*cdf0e10cSrcweir i_rImpl.m_xRepository->createGraph(xManifest), uno::UNO_SET_THROW); 759*cdf0e10cSrcweir const uno::Reference<container::XEnumeration> xEnum( 760*cdf0e10cSrcweir i_rImpl.m_xManifest->getStatements(0, 761*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext), 762*cdf0e10cSrcweir getURI<rdf::URIs::PKG_DOCUMENT>(i_rImpl.m_xContext).get())); 763*cdf0e10cSrcweir 764*cdf0e10cSrcweir // document statement 765*cdf0e10cSrcweir i_rImpl.m_xManifest->addStatement(i_rImpl.m_xBaseURI.get(), 766*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext), 767*cdf0e10cSrcweir getURI<rdf::URIs::PKG_DOCUMENT>(i_rImpl.m_xContext).get()); 768*cdf0e10cSrcweir 769*cdf0e10cSrcweir OSL_ENSURE(i_rImpl.m_xBaseURI.is(), "base URI is null"); 770*cdf0e10cSrcweir OSL_ENSURE(i_rImpl.m_xRepository.is(), "repository is null"); 771*cdf0e10cSrcweir OSL_ENSURE(i_rImpl.m_xManifest.is(), "manifest is null"); 772*cdf0e10cSrcweir 773*cdf0e10cSrcweir if (rterr.hasValue()) { 774*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 775*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 776*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromStorage: " 777*cdf0e10cSrcweir "exception"), 0, rterr); 778*cdf0e10cSrcweir } 779*cdf0e10cSrcweir 780*cdf0e10cSrcweir if (err) { 781*cdf0e10cSrcweir if (handleError(iaioe, i_xHandler)) goto retry; 782*cdf0e10cSrcweir } 783*cdf0e10cSrcweir } 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir /** init Impl struct */ 786*cdf0e10cSrcweir static void init(struct DocumentMetadataAccess_Impl & i_rImpl) 787*cdf0e10cSrcweir { 788*cdf0e10cSrcweir try { 789*cdf0e10cSrcweir 790*cdf0e10cSrcweir i_rImpl.m_xManifest.set(i_rImpl.m_xRepository->createGraph( 791*cdf0e10cSrcweir getURIForStream(i_rImpl, 792*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(s_manifest))), 793*cdf0e10cSrcweir uno::UNO_SET_THROW); 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir // insert the document statement 796*cdf0e10cSrcweir i_rImpl.m_xManifest->addStatement(i_rImpl.m_xBaseURI.get(), 797*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext), 798*cdf0e10cSrcweir getURI<rdf::URIs::PKG_DOCUMENT>(i_rImpl.m_xContext).get()); 799*cdf0e10cSrcweir } catch (uno::Exception & e) { 800*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 801*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("init: unexpected exception"), 0, 802*cdf0e10cSrcweir uno::makeAny(e)); 803*cdf0e10cSrcweir } 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir // add top-level content files 806*cdf0e10cSrcweir if (!addContentOrStylesFileImpl(i_rImpl, 807*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(s_content))) { 808*cdf0e10cSrcweir throw uno::RuntimeException(); 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir if (!addContentOrStylesFileImpl(i_rImpl, 811*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(s_styles))) { 812*cdf0e10cSrcweir throw uno::RuntimeException(); 813*cdf0e10cSrcweir } 814*cdf0e10cSrcweir } 815*cdf0e10cSrcweir 816*cdf0e10cSrcweir 817*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////// 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir DocumentMetadataAccess::DocumentMetadataAccess( 820*cdf0e10cSrcweir uno::Reference< uno::XComponentContext > const & i_xContext, 821*cdf0e10cSrcweir const IXmlIdRegistrySupplier & i_rRegistrySupplier) 822*cdf0e10cSrcweir : m_pImpl(new DocumentMetadataAccess_Impl(i_xContext, i_rRegistrySupplier)) 823*cdf0e10cSrcweir { 824*cdf0e10cSrcweir // no initalization: must call loadFrom... 825*cdf0e10cSrcweir } 826*cdf0e10cSrcweir 827*cdf0e10cSrcweir DocumentMetadataAccess::DocumentMetadataAccess( 828*cdf0e10cSrcweir uno::Reference< uno::XComponentContext > const & i_xContext, 829*cdf0e10cSrcweir const IXmlIdRegistrySupplier & i_rRegistrySupplier, 830*cdf0e10cSrcweir ::rtl::OUString const & i_rURI) 831*cdf0e10cSrcweir : m_pImpl(new DocumentMetadataAccess_Impl(i_xContext, i_rRegistrySupplier)) 832*cdf0e10cSrcweir { 833*cdf0e10cSrcweir OSL_ENSURE(i_rURI.getLength(), "DMA::DMA: no URI given!"); 834*cdf0e10cSrcweir OSL_ENSURE(i_rURI.endsWithAsciiL("/", 1), "DMA::DMA: URI without / given!"); 835*cdf0e10cSrcweir if (!i_rURI.endsWithAsciiL("/", 1)) throw uno::RuntimeException(); 836*cdf0e10cSrcweir m_pImpl->m_xBaseURI.set(rdf::URI::create(m_pImpl->m_xContext, i_rURI)); 837*cdf0e10cSrcweir m_pImpl->m_xRepository.set(rdf::Repository::create(m_pImpl->m_xContext), 838*cdf0e10cSrcweir uno::UNO_SET_THROW); 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir // init repository 841*cdf0e10cSrcweir init(*m_pImpl); 842*cdf0e10cSrcweir 843*cdf0e10cSrcweir OSL_ENSURE(m_pImpl->m_xBaseURI.is(), "base URI is null"); 844*cdf0e10cSrcweir OSL_ENSURE(m_pImpl->m_xRepository.is(), "repository is null"); 845*cdf0e10cSrcweir OSL_ENSURE(m_pImpl->m_xManifest.is(), "manifest is null"); 846*cdf0e10cSrcweir } 847*cdf0e10cSrcweir 848*cdf0e10cSrcweir DocumentMetadataAccess::~DocumentMetadataAccess() 849*cdf0e10cSrcweir { 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir 852*cdf0e10cSrcweir 853*cdf0e10cSrcweir // ::com::sun::star::rdf::XRepositorySupplier: 854*cdf0e10cSrcweir uno::Reference< rdf::XRepository > SAL_CALL 855*cdf0e10cSrcweir DocumentMetadataAccess::getRDFRepository() throw (uno::RuntimeException) 856*cdf0e10cSrcweir { 857*cdf0e10cSrcweir OSL_ENSURE(m_pImpl->m_xRepository.is(), "repository not initialized"); 858*cdf0e10cSrcweir return m_pImpl->m_xRepository; 859*cdf0e10cSrcweir } 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir // ::com::sun::star::rdf::XNode: 862*cdf0e10cSrcweir ::rtl::OUString SAL_CALL 863*cdf0e10cSrcweir DocumentMetadataAccess::getStringValue() throw (uno::RuntimeException) 864*cdf0e10cSrcweir { 865*cdf0e10cSrcweir return m_pImpl->m_xBaseURI->getStringValue(); 866*cdf0e10cSrcweir } 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir // ::com::sun::star::rdf::XURI: 869*cdf0e10cSrcweir ::rtl::OUString SAL_CALL 870*cdf0e10cSrcweir DocumentMetadataAccess::getNamespace() throw (uno::RuntimeException) 871*cdf0e10cSrcweir { 872*cdf0e10cSrcweir return m_pImpl->m_xBaseURI->getNamespace(); 873*cdf0e10cSrcweir } 874*cdf0e10cSrcweir 875*cdf0e10cSrcweir ::rtl::OUString SAL_CALL 876*cdf0e10cSrcweir DocumentMetadataAccess::getLocalName() throw (uno::RuntimeException) 877*cdf0e10cSrcweir { 878*cdf0e10cSrcweir return m_pImpl->m_xBaseURI->getLocalName(); 879*cdf0e10cSrcweir } 880*cdf0e10cSrcweir 881*cdf0e10cSrcweir // ::com::sun::star::rdf::XDocumentMetadataAccess: 882*cdf0e10cSrcweir uno::Reference< rdf::XMetadatable > SAL_CALL 883*cdf0e10cSrcweir DocumentMetadataAccess::getElementByMetadataReference( 884*cdf0e10cSrcweir const ::com::sun::star::beans::StringPair & i_rReference) 885*cdf0e10cSrcweir throw (uno::RuntimeException) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir const IXmlIdRegistry * pReg( 888*cdf0e10cSrcweir m_pImpl->m_rXmlIdRegistrySupplier.GetXmlIdRegistry() ); 889*cdf0e10cSrcweir if (!pReg) { 890*cdf0e10cSrcweir throw uno::RuntimeException(::rtl::OUString::createFromAscii( 891*cdf0e10cSrcweir "DocumentMetadataAccess::getElementByXmlId: no registry"), *this); 892*cdf0e10cSrcweir } 893*cdf0e10cSrcweir return pReg->GetElementByMetadataReference(i_rReference); 894*cdf0e10cSrcweir } 895*cdf0e10cSrcweir 896*cdf0e10cSrcweir uno::Reference< rdf::XMetadatable > SAL_CALL 897*cdf0e10cSrcweir DocumentMetadataAccess::getElementByURI( 898*cdf0e10cSrcweir const uno::Reference< rdf::XURI > & i_xURI ) 899*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException) 900*cdf0e10cSrcweir { 901*cdf0e10cSrcweir if (!i_xURI.is()) { 902*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 903*cdf0e10cSrcweir "DocumentMetadataAccess::getElementByURI: URI is null"), *this, 0); 904*cdf0e10cSrcweir } 905*cdf0e10cSrcweir 906*cdf0e10cSrcweir const ::rtl::OUString baseURI( m_pImpl->m_xBaseURI->getStringValue() ); 907*cdf0e10cSrcweir const ::rtl::OUString name( i_xURI->getStringValue() ); 908*cdf0e10cSrcweir if (!name.match(baseURI)) { 909*cdf0e10cSrcweir return 0; 910*cdf0e10cSrcweir } 911*cdf0e10cSrcweir const ::rtl::OUString relName( name.copy(baseURI.getLength()) ); 912*cdf0e10cSrcweir ::rtl::OUString path; 913*cdf0e10cSrcweir ::rtl::OUString idref; 914*cdf0e10cSrcweir if (!splitXmlId(relName, path, idref)) { 915*cdf0e10cSrcweir return 0; 916*cdf0e10cSrcweir } 917*cdf0e10cSrcweir 918*cdf0e10cSrcweir return getElementByMetadataReference( beans::StringPair(path, idref) ); 919*cdf0e10cSrcweir } 920*cdf0e10cSrcweir 921*cdf0e10cSrcweir 922*cdf0e10cSrcweir uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL 923*cdf0e10cSrcweir DocumentMetadataAccess::getMetadataGraphsWithType( 924*cdf0e10cSrcweir const uno::Reference<rdf::XURI> & i_xType) 925*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException) 926*cdf0e10cSrcweir { 927*cdf0e10cSrcweir if (!i_xType.is()) { 928*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 929*cdf0e10cSrcweir "DocumentMetadataAccess::getMetadataGraphsWithType: " 930*cdf0e10cSrcweir "type is null"), *this, 0); 931*cdf0e10cSrcweir } 932*cdf0e10cSrcweir 933*cdf0e10cSrcweir ::comphelper::SequenceAsVector< uno::Reference< rdf::XURI > > ret; 934*cdf0e10cSrcweir const ::std::vector< uno::Reference< rdf::XURI > > parts( 935*cdf0e10cSrcweir getAllParts(*m_pImpl) ); 936*cdf0e10cSrcweir ::std::remove_copy_if(parts.begin(), parts.end(), 937*cdf0e10cSrcweir ::std::back_inserter(ret), 938*cdf0e10cSrcweir ::boost::bind( 939*cdf0e10cSrcweir ::std::logical_not<bool>(), 940*cdf0e10cSrcweir ::boost::bind(&isPartOfType, ::boost::ref(*m_pImpl), _1, i_xType) )); 941*cdf0e10cSrcweir return ret.getAsConstList(); 942*cdf0e10cSrcweir } 943*cdf0e10cSrcweir 944*cdf0e10cSrcweir uno::Reference<rdf::XURI> SAL_CALL 945*cdf0e10cSrcweir DocumentMetadataAccess::addMetadataFile(const ::rtl::OUString & i_rFileName, 946*cdf0e10cSrcweir const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes) 947*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 948*cdf0e10cSrcweir container::ElementExistException) 949*cdf0e10cSrcweir { 950*cdf0e10cSrcweir if (!isFileNameValid(i_rFileName)) { 951*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 952*cdf0e10cSrcweir "DocumentMetadataAccess::addMetadataFile: invalid FileName"), 953*cdf0e10cSrcweir *this, 0); 954*cdf0e10cSrcweir } 955*cdf0e10cSrcweir if (isReservedFile(i_rFileName)) { 956*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 957*cdf0e10cSrcweir "DocumentMetadataAccess::addMetadataFile:" 958*cdf0e10cSrcweir "invalid FileName: reserved"), *this, 0); 959*cdf0e10cSrcweir } 960*cdf0e10cSrcweir for (sal_Int32 i = 0; i < i_rTypes.getLength(); ++i) { 961*cdf0e10cSrcweir if (!i_rTypes[i].is()) { 962*cdf0e10cSrcweir throw lang::IllegalArgumentException( 963*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 964*cdf0e10cSrcweir "DocumentMetadataAccess::addMetadataFile: " 965*cdf0e10cSrcweir "null type"), *this, 2); 966*cdf0e10cSrcweir } 967*cdf0e10cSrcweir } 968*cdf0e10cSrcweir 969*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xGraphName( 970*cdf0e10cSrcweir getURIForStream(*m_pImpl, i_rFileName) ); 971*cdf0e10cSrcweir 972*cdf0e10cSrcweir try { 973*cdf0e10cSrcweir m_pImpl->m_xRepository->createGraph(xGraphName); 974*cdf0e10cSrcweir } catch (rdf::RepositoryException & e) { 975*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 976*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 977*cdf0e10cSrcweir "DocumentMetadataAccess::addMetadataFile: exception"), 978*cdf0e10cSrcweir *this, uno::makeAny(e)); 979*cdf0e10cSrcweir // note: all other exceptions are propagated 980*cdf0e10cSrcweir } 981*cdf0e10cSrcweir 982*cdf0e10cSrcweir addMetadataFileImpl(*m_pImpl, i_rFileName, i_rTypes); 983*cdf0e10cSrcweir return xGraphName; 984*cdf0e10cSrcweir } 985*cdf0e10cSrcweir 986*cdf0e10cSrcweir uno::Reference<rdf::XURI> SAL_CALL 987*cdf0e10cSrcweir DocumentMetadataAccess::importMetadataFile(::sal_Int16 i_Format, 988*cdf0e10cSrcweir const uno::Reference< io::XInputStream > & i_xInStream, 989*cdf0e10cSrcweir const ::rtl::OUString & i_rFileName, 990*cdf0e10cSrcweir const uno::Reference< rdf::XURI > & i_xBaseURI, 991*cdf0e10cSrcweir const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes) 992*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 993*cdf0e10cSrcweir datatransfer::UnsupportedFlavorException, 994*cdf0e10cSrcweir container::ElementExistException, rdf::ParseException, io::IOException) 995*cdf0e10cSrcweir { 996*cdf0e10cSrcweir if (!isFileNameValid(i_rFileName)) { 997*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 998*cdf0e10cSrcweir "DocumentMetadataAccess::importMetadataFile: invalid FileName"), 999*cdf0e10cSrcweir *this, 0); 1000*cdf0e10cSrcweir } 1001*cdf0e10cSrcweir if (isReservedFile(i_rFileName)) { 1002*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1003*cdf0e10cSrcweir "DocumentMetadataAccess::importMetadataFile:" 1004*cdf0e10cSrcweir "invalid FileName: reserved"), *this, 0); 1005*cdf0e10cSrcweir } 1006*cdf0e10cSrcweir for (sal_Int32 i = 0; i < i_rTypes.getLength(); ++i) { 1007*cdf0e10cSrcweir if (!i_rTypes[i].is()) { 1008*cdf0e10cSrcweir throw lang::IllegalArgumentException( 1009*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1010*cdf0e10cSrcweir "DocumentMetadataAccess::importMetadataFile: null type"), 1011*cdf0e10cSrcweir *this, 5); 1012*cdf0e10cSrcweir } 1013*cdf0e10cSrcweir } 1014*cdf0e10cSrcweir 1015*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xGraphName( 1016*cdf0e10cSrcweir getURIForStream(*m_pImpl, i_rFileName) ); 1017*cdf0e10cSrcweir 1018*cdf0e10cSrcweir try { 1019*cdf0e10cSrcweir m_pImpl->m_xRepository->importGraph( 1020*cdf0e10cSrcweir i_Format, i_xInStream, xGraphName, i_xBaseURI); 1021*cdf0e10cSrcweir } catch (rdf::RepositoryException & e) { 1022*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 1023*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1024*cdf0e10cSrcweir "DocumentMetadataAccess::importMetadataFile: " 1025*cdf0e10cSrcweir "RepositoryException"), *this, uno::makeAny(e)); 1026*cdf0e10cSrcweir // note: all other exceptions are propagated 1027*cdf0e10cSrcweir } 1028*cdf0e10cSrcweir 1029*cdf0e10cSrcweir // add to manifest 1030*cdf0e10cSrcweir addMetadataFileImpl(*m_pImpl, i_rFileName, i_rTypes); 1031*cdf0e10cSrcweir return xGraphName; 1032*cdf0e10cSrcweir } 1033*cdf0e10cSrcweir 1034*cdf0e10cSrcweir void SAL_CALL 1035*cdf0e10cSrcweir DocumentMetadataAccess::removeMetadataFile( 1036*cdf0e10cSrcweir const uno::Reference< rdf::XURI > & i_xGraphName) 1037*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 1038*cdf0e10cSrcweir container::NoSuchElementException) 1039*cdf0e10cSrcweir { 1040*cdf0e10cSrcweir try { 1041*cdf0e10cSrcweir m_pImpl->m_xRepository->destroyGraph(i_xGraphName); 1042*cdf0e10cSrcweir } catch (rdf::RepositoryException & e) { 1043*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 1044*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1045*cdf0e10cSrcweir "DocumentMetadataAccess::removeMetadataFile: " 1046*cdf0e10cSrcweir "RepositoryException"), *this, uno::makeAny(e)); 1047*cdf0e10cSrcweir // note: all other exceptions are propagated 1048*cdf0e10cSrcweir } 1049*cdf0e10cSrcweir 1050*cdf0e10cSrcweir // remove file from manifest 1051*cdf0e10cSrcweir removeFile(*m_pImpl, i_xGraphName.get()); 1052*cdf0e10cSrcweir } 1053*cdf0e10cSrcweir 1054*cdf0e10cSrcweir void SAL_CALL 1055*cdf0e10cSrcweir DocumentMetadataAccess::addContentOrStylesFile( 1056*cdf0e10cSrcweir const ::rtl::OUString & i_rFileName) 1057*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 1058*cdf0e10cSrcweir container::ElementExistException) 1059*cdf0e10cSrcweir { 1060*cdf0e10cSrcweir if (!isFileNameValid(i_rFileName)) { 1061*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1062*cdf0e10cSrcweir "DocumentMetadataAccess::addContentOrStylesFile: " 1063*cdf0e10cSrcweir "invalid FileName"), *this, 0); 1064*cdf0e10cSrcweir } 1065*cdf0e10cSrcweir 1066*cdf0e10cSrcweir if (!addContentOrStylesFileImpl(*m_pImpl, i_rFileName)) { 1067*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1068*cdf0e10cSrcweir "DocumentMetadataAccess::addContentOrStylesFile: " 1069*cdf0e10cSrcweir "invalid FileName: must end with content.xml or styles.xml"), 1070*cdf0e10cSrcweir *this, 0); 1071*cdf0e10cSrcweir } 1072*cdf0e10cSrcweir } 1073*cdf0e10cSrcweir 1074*cdf0e10cSrcweir void SAL_CALL 1075*cdf0e10cSrcweir DocumentMetadataAccess::removeContentOrStylesFile( 1076*cdf0e10cSrcweir const ::rtl::OUString & i_rFileName) 1077*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 1078*cdf0e10cSrcweir container::NoSuchElementException) 1079*cdf0e10cSrcweir { 1080*cdf0e10cSrcweir if (!isFileNameValid(i_rFileName)) { 1081*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1082*cdf0e10cSrcweir "DocumentMetadataAccess::removeContentOrStylesFile: " 1083*cdf0e10cSrcweir "invalid FileName"), *this, 0); 1084*cdf0e10cSrcweir } 1085*cdf0e10cSrcweir 1086*cdf0e10cSrcweir try { 1087*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xPart( 1088*cdf0e10cSrcweir getURIForStream(*m_pImpl, i_rFileName) ); 1089*cdf0e10cSrcweir const uno::Reference<container::XEnumeration> xEnum( 1090*cdf0e10cSrcweir m_pImpl->m_xManifest->getStatements( m_pImpl->m_xBaseURI.get(), 1091*cdf0e10cSrcweir getURI<rdf::URIs::PKG_HASPART>(m_pImpl->m_xContext), 1092*cdf0e10cSrcweir xPart.get()), 1093*cdf0e10cSrcweir uno::UNO_SET_THROW); 1094*cdf0e10cSrcweir if (!xEnum->hasMoreElements()) { 1095*cdf0e10cSrcweir throw container::NoSuchElementException( 1096*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1097*cdf0e10cSrcweir "DocumentMetadataAccess::removeContentOrStylesFile: " 1098*cdf0e10cSrcweir "cannot find stream in manifest graph: ") + i_rFileName, 1099*cdf0e10cSrcweir *this); 1100*cdf0e10cSrcweir } 1101*cdf0e10cSrcweir 1102*cdf0e10cSrcweir // remove file from manifest 1103*cdf0e10cSrcweir removeFile(*m_pImpl, xPart); 1104*cdf0e10cSrcweir 1105*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 1106*cdf0e10cSrcweir throw; 1107*cdf0e10cSrcweir } catch (uno::Exception & e) { 1108*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 1109*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1110*cdf0e10cSrcweir "DocumentMetadataAccess::removeContentOrStylesFile: exception"), 1111*cdf0e10cSrcweir *this, uno::makeAny(e)); 1112*cdf0e10cSrcweir } 1113*cdf0e10cSrcweir } 1114*cdf0e10cSrcweir 1115*cdf0e10cSrcweir void SAL_CALL DocumentMetadataAccess::loadMetadataFromStorage( 1116*cdf0e10cSrcweir const uno::Reference< embed::XStorage > & i_xStorage, 1117*cdf0e10cSrcweir const uno::Reference<rdf::XURI> & i_xBaseURI, 1118*cdf0e10cSrcweir const uno::Reference<task::XInteractionHandler> & i_xHandler) 1119*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 1120*cdf0e10cSrcweir lang::WrappedTargetException) 1121*cdf0e10cSrcweir { 1122*cdf0e10cSrcweir if (!i_xStorage.is()) { 1123*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1124*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromStorage: " 1125*cdf0e10cSrcweir "storage is null"), *this, 0); 1126*cdf0e10cSrcweir } 1127*cdf0e10cSrcweir if (!i_xBaseURI.is()) { 1128*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1129*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromStorage: " 1130*cdf0e10cSrcweir "base URI is null"), *this, 1); 1131*cdf0e10cSrcweir } 1132*cdf0e10cSrcweir const ::rtl::OUString baseURI( i_xBaseURI->getStringValue()); 1133*cdf0e10cSrcweir if (baseURI.indexOf('#') >= 0) { 1134*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1135*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromStorage: " 1136*cdf0e10cSrcweir "base URI not absolute"), *this, 1); 1137*cdf0e10cSrcweir } 1138*cdf0e10cSrcweir if (!baseURI.getLength() || !baseURI.endsWithAsciiL("/", 1)) { 1139*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1140*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromStorage: " 1141*cdf0e10cSrcweir "base URI does not end with slash"), *this, 1); 1142*cdf0e10cSrcweir } 1143*cdf0e10cSrcweir 1144*cdf0e10cSrcweir initLoading(*m_pImpl, i_xStorage, i_xBaseURI, i_xHandler); 1145*cdf0e10cSrcweir 1146*cdf0e10cSrcweir std::set< ::rtl::OUString > StgFiles; 1147*cdf0e10cSrcweir collectFilesFromStorage(i_xStorage, 1148*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(""), StgFiles); 1149*cdf0e10cSrcweir 1150*cdf0e10cSrcweir std::vector< ::rtl::OUString > MfstMetadataFiles; 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir try { 1153*cdf0e10cSrcweir const ::std::vector< uno::Reference< rdf::XURI > > parts( 1154*cdf0e10cSrcweir getAllParts(*m_pImpl) ); 1155*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xContentFile( 1156*cdf0e10cSrcweir getURI<rdf::URIs::ODF_CONTENTFILE>(m_pImpl->m_xContext)); 1157*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xStylesFile( 1158*cdf0e10cSrcweir getURI<rdf::URIs::ODF_STYLESFILE>(m_pImpl->m_xContext)); 1159*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xMetadataFile( 1160*cdf0e10cSrcweir getURI<rdf::URIs::PKG_METADATAFILE>(m_pImpl->m_xContext)); 1161*cdf0e10cSrcweir const sal_Int32 len( baseURI.getLength() ); 1162*cdf0e10cSrcweir const ::rtl::OUString manifest ( 1163*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(s_manifest)); 1164*cdf0e10cSrcweir for (::std::vector< uno::Reference< rdf::XURI > >::const_iterator it 1165*cdf0e10cSrcweir = parts.begin(); 1166*cdf0e10cSrcweir it != parts.end(); ++it) { 1167*cdf0e10cSrcweir const ::rtl::OUString name((*it)->getStringValue()); 1168*cdf0e10cSrcweir if (!name.match(baseURI)) { 1169*cdf0e10cSrcweir OSL_TRACE("loadMetadataFromStorage: graph not in document: %s", 1170*cdf0e10cSrcweir ::rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8) 1171*cdf0e10cSrcweir .getStr()); 1172*cdf0e10cSrcweir continue; 1173*cdf0e10cSrcweir } 1174*cdf0e10cSrcweir const ::rtl::OUString relName( name.copy(len) ); 1175*cdf0e10cSrcweir if (relName == manifest) { 1176*cdf0e10cSrcweir OSL_TRACE("loadMetadataFromStorage: " 1177*cdf0e10cSrcweir "found ourselves a recursive manifest!"); 1178*cdf0e10cSrcweir continue; 1179*cdf0e10cSrcweir } 1180*cdf0e10cSrcweir // remove found items from StgFiles 1181*cdf0e10cSrcweir StgFiles.erase(relName); 1182*cdf0e10cSrcweir if (isContentFile(relName)) { 1183*cdf0e10cSrcweir if (!isPartOfType(*m_pImpl, *it, xContentFile)) { 1184*cdf0e10cSrcweir const uno::Reference <rdf::XURI> xName( 1185*cdf0e10cSrcweir getURIForStream(*m_pImpl, relName) ); 1186*cdf0e10cSrcweir // add missing type statement 1187*cdf0e10cSrcweir m_pImpl->m_xManifest->addStatement(xName.get(), 1188*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(m_pImpl->m_xContext), 1189*cdf0e10cSrcweir xContentFile.get()); 1190*cdf0e10cSrcweir } 1191*cdf0e10cSrcweir } else if (isStylesFile(relName)) { 1192*cdf0e10cSrcweir if (!isPartOfType(*m_pImpl, *it, xStylesFile)) { 1193*cdf0e10cSrcweir const uno::Reference <rdf::XURI> xName( 1194*cdf0e10cSrcweir getURIForStream(*m_pImpl, relName) ); 1195*cdf0e10cSrcweir // add missing type statement 1196*cdf0e10cSrcweir m_pImpl->m_xManifest->addStatement(xName.get(), 1197*cdf0e10cSrcweir getURI<rdf::URIs::RDF_TYPE>(m_pImpl->m_xContext), 1198*cdf0e10cSrcweir xStylesFile.get()); 1199*cdf0e10cSrcweir } 1200*cdf0e10cSrcweir } else if (isReservedFile(relName)) { 1201*cdf0e10cSrcweir OSL_TRACE("loadMetadataFromStorage: " 1202*cdf0e10cSrcweir "reserved file name in manifest"); 1203*cdf0e10cSrcweir } else { 1204*cdf0e10cSrcweir if (isPartOfType(*m_pImpl, *it, xMetadataFile)) { 1205*cdf0e10cSrcweir MfstMetadataFiles.push_back(relName); 1206*cdf0e10cSrcweir } 1207*cdf0e10cSrcweir // do not add statement for MetadataFile; it could be 1208*cdf0e10cSrcweir // something else! just ignore it... 1209*cdf0e10cSrcweir } 1210*cdf0e10cSrcweir } 1211*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 1212*cdf0e10cSrcweir throw; 1213*cdf0e10cSrcweir } catch (uno::Exception & e) { 1214*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 1215*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1216*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromStorage: " 1217*cdf0e10cSrcweir "exception"), *this, uno::makeAny(e)); 1218*cdf0e10cSrcweir } 1219*cdf0e10cSrcweir 1220*cdf0e10cSrcweir std::for_each(StgFiles.begin(), StgFiles.end(), 1221*cdf0e10cSrcweir boost::bind(addContentOrStylesFileImpl, boost::ref(*m_pImpl), _1)); 1222*cdf0e10cSrcweir 1223*cdf0e10cSrcweir std::for_each(MfstMetadataFiles.begin(), MfstMetadataFiles.end(), 1224*cdf0e10cSrcweir boost::bind(importFile, boost::ref(*m_pImpl), 1225*cdf0e10cSrcweir i_xStorage, baseURI, i_xHandler, _1)); 1226*cdf0e10cSrcweir } 1227*cdf0e10cSrcweir 1228*cdf0e10cSrcweir void SAL_CALL DocumentMetadataAccess::storeMetadataToStorage( 1229*cdf0e10cSrcweir const uno::Reference< embed::XStorage > & i_xStorage) 1230*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 1231*cdf0e10cSrcweir lang::WrappedTargetException) 1232*cdf0e10cSrcweir { 1233*cdf0e10cSrcweir if (!i_xStorage.is()) { 1234*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1235*cdf0e10cSrcweir "DocumentMetadataAccess::storeMetadataToStorage: " 1236*cdf0e10cSrcweir "storage is null"), *this, 0); 1237*cdf0e10cSrcweir } 1238*cdf0e10cSrcweir 1239*cdf0e10cSrcweir // export manifest 1240*cdf0e10cSrcweir const ::rtl::OUString manifest ( 1241*cdf0e10cSrcweir ::rtl::OUString::createFromAscii(s_manifest)); 1242*cdf0e10cSrcweir const uno::Reference <rdf::XURI> xManifest( 1243*cdf0e10cSrcweir getURIForStream(*m_pImpl, manifest) ); 1244*cdf0e10cSrcweir const ::rtl::OUString baseURI( m_pImpl->m_xBaseURI->getStringValue() ); 1245*cdf0e10cSrcweir try { 1246*cdf0e10cSrcweir writeStream(*m_pImpl, i_xStorage, xManifest, manifest, baseURI); 1247*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 1248*cdf0e10cSrcweir throw; 1249*cdf0e10cSrcweir } catch (io::IOException & e) { 1250*cdf0e10cSrcweir throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( 1251*cdf0e10cSrcweir "storeMetadataToStorage: IO exception"), *this, uno::makeAny(e)); 1252*cdf0e10cSrcweir } catch (uno::Exception & e) { 1253*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 1254*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1255*cdf0e10cSrcweir "storeMetadataToStorage: exception"), *this, uno::makeAny(e)); 1256*cdf0e10cSrcweir } 1257*cdf0e10cSrcweir 1258*cdf0e10cSrcweir // export metadata streams 1259*cdf0e10cSrcweir try { 1260*cdf0e10cSrcweir const uno::Sequence<uno::Reference<rdf::XURI> > graphs( 1261*cdf0e10cSrcweir m_pImpl->m_xRepository->getGraphNames()); 1262*cdf0e10cSrcweir const sal_Int32 len( baseURI.getLength() ); 1263*cdf0e10cSrcweir for (sal_Int32 i = 0; i < graphs.getLength(); ++i) { 1264*cdf0e10cSrcweir const uno::Reference<rdf::XURI> xName(graphs[i]); 1265*cdf0e10cSrcweir const ::rtl::OUString name(xName->getStringValue()); 1266*cdf0e10cSrcweir if (!name.match(baseURI)) { 1267*cdf0e10cSrcweir OSL_TRACE("storeMetadataToStorage: graph not in document: %s", 1268*cdf0e10cSrcweir ::rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8) 1269*cdf0e10cSrcweir .getStr()); 1270*cdf0e10cSrcweir continue; 1271*cdf0e10cSrcweir } 1272*cdf0e10cSrcweir const ::rtl::OUString relName( name.copy(len) ); 1273*cdf0e10cSrcweir if (relName == manifest) { 1274*cdf0e10cSrcweir continue; 1275*cdf0e10cSrcweir } 1276*cdf0e10cSrcweir if (!isFileNameValid(relName) || isReservedFile(relName)) { 1277*cdf0e10cSrcweir OSL_TRACE("storeMetadataToStorage: invalid file name: %s", 1278*cdf0e10cSrcweir ::rtl::OUStringToOString(relName, RTL_TEXTENCODING_UTF8) 1279*cdf0e10cSrcweir .getStr()); 1280*cdf0e10cSrcweir continue; 1281*cdf0e10cSrcweir } 1282*cdf0e10cSrcweir try { 1283*cdf0e10cSrcweir writeStream(*m_pImpl, i_xStorage, xName, relName, baseURI); 1284*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 1285*cdf0e10cSrcweir throw; 1286*cdf0e10cSrcweir } catch (io::IOException & e) { 1287*cdf0e10cSrcweir throw lang::WrappedTargetException( 1288*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1289*cdf0e10cSrcweir "storeMetadataToStorage: IO exception"), 1290*cdf0e10cSrcweir *this, uno::makeAny(e)); 1291*cdf0e10cSrcweir } catch (uno::Exception & e) { 1292*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 1293*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1294*cdf0e10cSrcweir "storeMetadataToStorage: exception"), 1295*cdf0e10cSrcweir *this, uno::makeAny(e)); 1296*cdf0e10cSrcweir } 1297*cdf0e10cSrcweir } 1298*cdf0e10cSrcweir } catch (rdf::RepositoryException & e) { 1299*cdf0e10cSrcweir throw lang::WrappedTargetRuntimeException( 1300*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1301*cdf0e10cSrcweir "storeMetadataToStorage: exception"), *this, uno::makeAny(e)); 1302*cdf0e10cSrcweir } 1303*cdf0e10cSrcweir } 1304*cdf0e10cSrcweir 1305*cdf0e10cSrcweir void SAL_CALL 1306*cdf0e10cSrcweir DocumentMetadataAccess::loadMetadataFromMedium( 1307*cdf0e10cSrcweir const uno::Sequence< beans::PropertyValue > & i_rMedium) 1308*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 1309*cdf0e10cSrcweir lang::WrappedTargetException) 1310*cdf0e10cSrcweir { 1311*cdf0e10cSrcweir uno::Reference<io::XInputStream> xIn; 1312*cdf0e10cSrcweir ::comphelper::MediaDescriptor md(i_rMedium); 1313*cdf0e10cSrcweir ::rtl::OUString URL; 1314*cdf0e10cSrcweir md[ ::comphelper::MediaDescriptor::PROP_URL() ] >>= URL; 1315*cdf0e10cSrcweir ::rtl::OUString BaseURL; 1316*cdf0e10cSrcweir md[ ::comphelper::MediaDescriptor::PROP_DOCUMENTBASEURL() ] >>= BaseURL; 1317*cdf0e10cSrcweir if (md.addInputStream()) { 1318*cdf0e10cSrcweir md[ ::comphelper::MediaDescriptor::PROP_INPUTSTREAM() ] >>= xIn; 1319*cdf0e10cSrcweir } 1320*cdf0e10cSrcweir if (!xIn.is() && URL.equalsAscii("")) { 1321*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1322*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromMedium: " 1323*cdf0e10cSrcweir "inalid medium: no URL, no input stream"), *this, 0); 1324*cdf0e10cSrcweir } 1325*cdf0e10cSrcweir uno::Reference<embed::XStorage> xStorage; 1326*cdf0e10cSrcweir try { 1327*cdf0e10cSrcweir const uno::Reference<lang::XMultiServiceFactory> xMsf ( 1328*cdf0e10cSrcweir m_pImpl->m_xContext->getServiceManager(), uno::UNO_QUERY_THROW); 1329*cdf0e10cSrcweir if (xIn.is()) { 1330*cdf0e10cSrcweir xStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream( 1331*cdf0e10cSrcweir xIn, xMsf); 1332*cdf0e10cSrcweir } else { // fallback to url 1333*cdf0e10cSrcweir xStorage = ::comphelper::OStorageHelper::GetStorageFromURL2( 1334*cdf0e10cSrcweir URL, embed::ElementModes::READ, xMsf); 1335*cdf0e10cSrcweir } 1336*cdf0e10cSrcweir } catch (uno::RuntimeException &) { 1337*cdf0e10cSrcweir throw; 1338*cdf0e10cSrcweir } catch (io::IOException &) { 1339*cdf0e10cSrcweir throw; 1340*cdf0e10cSrcweir } catch (uno::Exception & e) { 1341*cdf0e10cSrcweir throw lang::WrappedTargetException( 1342*cdf0e10cSrcweir ::rtl::OUString::createFromAscii( 1343*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromMedium: " 1344*cdf0e10cSrcweir "exception"), *this, uno::makeAny(e)); 1345*cdf0e10cSrcweir } 1346*cdf0e10cSrcweir if (!xStorage.is()) { 1347*cdf0e10cSrcweir throw uno::RuntimeException(::rtl::OUString::createFromAscii( 1348*cdf0e10cSrcweir "DocumentMetadataAccess::loadMetadataFromMedium: " 1349*cdf0e10cSrcweir "cannot get Storage"), *this); 1350*cdf0e10cSrcweir } 1351*cdf0e10cSrcweir uno::Reference<rdf::XURI> xBaseURI; 1352*cdf0e10cSrcweir try { 1353*cdf0e10cSrcweir xBaseURI = createBaseURI(m_pImpl->m_xContext, xStorage, BaseURL); 1354*cdf0e10cSrcweir } catch (uno::Exception &) { 1355*cdf0e10cSrcweir // fall back to URL 1356*cdf0e10cSrcweir try { 1357*cdf0e10cSrcweir xBaseURI = createBaseURI(m_pImpl->m_xContext, xStorage, URL); 1358*cdf0e10cSrcweir } catch (uno::Exception &) { 1359*cdf0e10cSrcweir OSL_ENSURE(false, "cannot create base URI"); 1360*cdf0e10cSrcweir } 1361*cdf0e10cSrcweir } 1362*cdf0e10cSrcweir uno::Reference<task::XInteractionHandler> xIH; 1363*cdf0e10cSrcweir md[ ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER() ] >>= xIH; 1364*cdf0e10cSrcweir loadMetadataFromStorage(xStorage, xBaseURI, xIH); 1365*cdf0e10cSrcweir } 1366*cdf0e10cSrcweir 1367*cdf0e10cSrcweir void SAL_CALL 1368*cdf0e10cSrcweir DocumentMetadataAccess::storeMetadataToMedium( 1369*cdf0e10cSrcweir const uno::Sequence< beans::PropertyValue > & i_rMedium) 1370*cdf0e10cSrcweir throw (uno::RuntimeException, lang::IllegalArgumentException, 1371*cdf0e10cSrcweir lang::WrappedTargetException) 1372*cdf0e10cSrcweir { 1373*cdf0e10cSrcweir ::comphelper::MediaDescriptor md(i_rMedium); 1374*cdf0e10cSrcweir ::rtl::OUString URL; 1375*cdf0e10cSrcweir md[ ::comphelper::MediaDescriptor::PROP_URL() ] >>= URL; 1376*cdf0e10cSrcweir if (URL.equalsAscii("")) { 1377*cdf0e10cSrcweir throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( 1378*cdf0e10cSrcweir "DocumentMetadataAccess::storeMetadataToMedium: " 1379*cdf0e10cSrcweir "invalid medium: no URL"), *this, 0); 1380*cdf0e10cSrcweir } 1381*cdf0e10cSrcweir 1382*cdf0e10cSrcweir SfxMedium aMedium(i_rMedium); 1383*cdf0e10cSrcweir uno::Reference<embed::XStorage> xStorage(aMedium.GetOutputStorage()); 1384*cdf0e10cSrcweir 1385*cdf0e10cSrcweir bool sfx(false); 1386*cdf0e10cSrcweir if (xStorage.is()) { 1387*cdf0e10cSrcweir sfx = true; 1388*cdf0e10cSrcweir } else { 1389*cdf0e10cSrcweir const uno::Reference<lang::XMultiServiceFactory> xMsf ( 1390*cdf0e10cSrcweir m_pImpl->m_xContext->getServiceManager(), uno::UNO_QUERY_THROW); 1391*cdf0e10cSrcweir xStorage = ::comphelper::OStorageHelper::GetStorageFromURL2( 1392*cdf0e10cSrcweir URL, embed::ElementModes::WRITE, xMsf); 1393*cdf0e10cSrcweir } 1394*cdf0e10cSrcweir 1395*cdf0e10cSrcweir if (!xStorage.is()) { 1396*cdf0e10cSrcweir throw uno::RuntimeException(::rtl::OUString::createFromAscii( 1397*cdf0e10cSrcweir "DocumentMetadataAccess::storeMetadataToMedium: " 1398*cdf0e10cSrcweir "cannot get Storage"), *this); 1399*cdf0e10cSrcweir } 1400*cdf0e10cSrcweir // set MIME type of the storage 1401*cdf0e10cSrcweir ::comphelper::MediaDescriptor::const_iterator iter 1402*cdf0e10cSrcweir = md.find(::comphelper::MediaDescriptor::PROP_MEDIATYPE()); 1403*cdf0e10cSrcweir if (iter != md.end()) { 1404*cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xProps(xStorage, 1405*cdf0e10cSrcweir uno::UNO_QUERY_THROW); 1406*cdf0e10cSrcweir try { 1407*cdf0e10cSrcweir // this is NOT supported in FileSystemStorage 1408*cdf0e10cSrcweir xProps->setPropertyValue( 1409*cdf0e10cSrcweir ::comphelper::MediaDescriptor::PROP_MEDIATYPE(), 1410*cdf0e10cSrcweir iter->second); 1411*cdf0e10cSrcweir } catch (uno::Exception &) { } 1412*cdf0e10cSrcweir } 1413*cdf0e10cSrcweir storeMetadataToStorage(xStorage); 1414*cdf0e10cSrcweir 1415*cdf0e10cSrcweir if (sfx) { 1416*cdf0e10cSrcweir const sal_Bool bOk = aMedium.Commit(); 1417*cdf0e10cSrcweir aMedium.Close(); 1418*cdf0e10cSrcweir if ( !bOk ) { 1419*cdf0e10cSrcweir sal_uInt32 nError = aMedium.GetError(); 1420*cdf0e10cSrcweir if ( nError == ERRCODE_NONE ) { 1421*cdf0e10cSrcweir nError = ERRCODE_IO_GENERAL; 1422*cdf0e10cSrcweir } 1423*cdf0e10cSrcweir task::ErrorCodeIOException ex( ::rtl::OUString(), 1424*cdf0e10cSrcweir uno::Reference< uno::XInterface >(), nError); 1425*cdf0e10cSrcweir throw lang::WrappedTargetException(::rtl::OUString(), *this, 1426*cdf0e10cSrcweir uno::makeAny(ex)); 1427*cdf0e10cSrcweir } 1428*cdf0e10cSrcweir } 1429*cdf0e10cSrcweir } 1430*cdf0e10cSrcweir 1431*cdf0e10cSrcweir } // namespace sfx2 1432*cdf0e10cSrcweir 1433