23#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
24#include <com/sun/star/beans/XPropertySet.hpp>
25#include <com/sun/star/embed/ElementModes.hpp>
26#include <com/sun/star/embed/XStorage.hpp>
27#include <com/sun/star/embed/XTransactedObject.hpp>
28#include <com/sun/star/frame/XTransientDocumentsDocumentContentIdentifierFactory.hpp>
29#include <com/sun/star/task/ErrorCodeIOException.hpp>
30#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
31#include <com/sun/star/rdf/FileFormat.hpp>
32#include <com/sun/star/rdf/ParseException.hpp>
33#include <com/sun/star/rdf/RepositoryException.hpp>
34#include <com/sun/star/rdf/URIs.hpp>
35#include <com/sun/star/rdf/Statement.hpp>
36#include <com/sun/star/rdf/URI.hpp>
37#include <com/sun/star/rdf/Repository.hpp>
39#include <rtl/ustrbuf.hxx>
41#include <rtl/bootstrap.hxx>
56#include <libxml/tree.h>
63#include <com/sun/star/uri/XUriReference.hpp>
64#include <com/sun/star/uri/UriReferenceFactory.hpp>
85 return !(xmlValidateNCName(
86 reinterpret_cast<const unsigned char*
>(
id.getStr()), 0));
93const char s_odfmime [] =
"application/vnd.oasis.opendocument.";
107 std::u16string_view i_rIdref)
120 uno::Reference<uno::XComponentContext>
const & i_xContext,
121 uno::Reference<frame::XModel>
const & i_xModel,
122 OUString
const & i_rPkgURI, std::u16string_view i_rSubDocument)
124 if (!i_xContext.is() || (!i_xModel.is() && i_rPkgURI.isEmpty())) {
125 throw uno::RuntimeException();
128 OUString pkgURI(i_rPkgURI);
133 if (pkgURI.isEmpty())
135 assert(i_xModel.is());
136 uno::Reference<frame::XTransientDocumentsDocumentContentIdentifierFactory>
138 i_xContext->getServiceManager()->createInstanceWithContext(
139 "com.sun.star.ucb.TransientDocumentsContentProvider",
141 uno::UNO_QUERY_THROW);
142 uno::Reference<ucb::XContentIdentifier>
const xContentId(
143 xTDDCIF->createDocumentContentIdentifier(i_xModel));
144 SAL_WARN_IF(!xContentId.is(),
"sfx",
"createBaseURI: cannot create ContentIdentifier");
145 if (!xContentId.is())
147 throw uno::RuntimeException(
"createBaseURI: cannot create ContentIdentifier");
149 pkgURI = xContentId->getContentIdentifier();
150 assert(!pkgURI.isEmpty());
151 if (!pkgURI.isEmpty() && !pkgURI.endsWith(
"/"))
159 if (pkgURI.startsWithIgnoreAsciiCase(
"vnd.sun.star.expand:", &pkgURI))
162 if (!pkgURI.isEmpty()) {
163 pkgURI = ::rtl::Uri::decode(
164 pkgURI, rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8);
165 if (pkgURI.isEmpty()) {
166 throw uno::RuntimeException();
168 ::rtl::Bootstrap::expandMacros(pkgURI);
172 const uno::Reference<uri::XUriReferenceFactory> xUriFactory =
173 uri::UriReferenceFactory::create( i_xContext);
174 uno::Reference< uri::XUriReference > xBaseURI;
176 const uno::Reference< uri::XUriReference > xPkgURI(
177 xUriFactory->parse(pkgURI), uno::UNO_SET_THROW );
178 xPkgURI->clearFragment();
184 xBaseURI.set( xPkgURI, uno::UNO_SET_THROW );
186 OUStringBuffer buf(64);
187 if (!xBaseURI->getUriReference().endsWith(
"/"))
189 const sal_Int32
count( xBaseURI->getPathSegmentCount() );
192 buf.append(xBaseURI->getPathSegment(
count - 1));
196 if (!i_rSubDocument.empty())
198 buf.append(OUString::Concat(i_rSubDocument) +
"/");
202 const uno::Reference< uri::XUriReference > xPathURI(
203 xUriFactory->parse(buf.makeStringAndClear()), uno::UNO_SET_THROW );
205 xUriFactory->makeAbsolute(xBaseURI, xPathURI,
206 true, uri::RelativeUriExcessParentSegments_ERROR),
210 return rdf::URI::create(i_xContext, xBaseURI->getUriReference());
223 uno::Reference<uno::XComponentContext> i_xContext,
233template<sal_Int16 Constant>
234static uno::Reference<rdf::XURI>
const &
235getURI(uno::Reference< uno::XComponentContext >
const & i_xContext)
237 static uno::Reference< rdf::XURI > xURI(
238 rdf::URI::createKnown(i_xContext, Constant), uno::UNO_SET_THROW);
246 if (i_rFileName.empty())
return false;
247 if (i_rFileName[0] ==
'/')
return false;
250 const OUString segment(
252 if (segment.isEmpty() ||
265 OUString & o_rDir, OUString& o_rRest)
267 const sal_Int32
idx(i_rPath.indexOf(
u'/'));
268 if (idx < 0 || idx >= i_rPath.getLength()) {
272 }
else if (
idx == 0 ||
idx == i_rPath.getLength() - 1) {
276 o_rDir = i_rPath.copy(0,
idx);
277 o_rRest = i_rPath.copy(
idx+1);
284 OUString & o_StreamName, OUString& o_Idref )
286 const size_t idx(i_XmlId.find(
u'#'));
287 if (
idx == std::u16string_view::npos)
289 o_StreamName = i_XmlId.substr(0,
idx);
290 o_Idref = i_XmlId.substr(
idx+1);
295static uno::Reference<rdf::XURI>
297 OUString
const& i_rPath)
299 const uno::Reference<rdf::XURI> xURI(
301 i_rImpl.
m_xBaseURI->getStringValue(), i_rPath),
310 uno::Reference<rdf::XURI>
const& i_xType,
311 OUString
const & i_rPath,
312 const uno::Sequence < uno::Reference< rdf::XURI > > * i_pTypes)
319 getURI<rdf::URIs::PKG_HASPART>(i_rImpl.
m_xContext),
322 getURI<rdf::URIs::RDF_TYPE>(i_rImpl.
m_xContext),
325 for (
const auto& rType : *i_pTypes) {
327 getURI<rdf::URIs::RDF_TYPE>(i_rImpl.
m_xContext),
331 }
catch (
const uno::RuntimeException &) {
333 }
catch (
const uno::Exception &) {
335 throw lang::WrappedTargetRuntimeException(
336 "addFile: exception",
nullptr, anyEx);
343 const OUString & i_rPath)
345 uno::Reference<rdf::XURI> xType;
347 xType.set(getURI<rdf::URIs::ODF_CONTENTFILE>(i_rImpl.
m_xContext));
349 xType.set(getURI<rdf::URIs::ODF_STYLESFILE>(i_rImpl.
m_xContext));
353 addFile(i_rImpl, xType, i_rPath,
nullptr);
360 const OUString & i_rPath,
361 const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
364 getURI<rdf::URIs::PKG_METADATAFILE>(i_rImpl.
m_xContext),
371 uno::Reference<rdf::XURI>
const& i_xPart)
373 if (!i_xPart.is())
throw uno::RuntimeException();
376 getURI<rdf::URIs::PKG_HASPART>(i_rImpl.
m_xContext),
379 getURI<rdf::URIs::RDF_TYPE>(i_rImpl.
m_xContext),
nullptr);
380 }
catch (
const uno::RuntimeException &) {
382 }
catch (
const uno::Exception &) {
384 throw lang::WrappedTargetRuntimeException(
385 "removeFile: exception",
390static ::std::vector< uno::Reference< rdf::XURI > >
393 ::std::vector< uno::Reference< rdf::XURI > > ret;
395 const uno::Reference<container::XEnumeration> xEnum(
397 getURI<rdf::URIs::PKG_HASPART>(i_rImpl.
m_xContext),
nullptr),
399 while (xEnum->hasMoreElements()) {
401 if (!(xEnum->nextElement() >>= stmt)) {
402 throw uno::RuntimeException();
404 const uno::Reference<rdf::XURI> xPart(stmt.Object,
406 if (!xPart.is())
continue;
407 ret.push_back(xPart);
410 }
catch (
const uno::RuntimeException &) {
412 }
catch (
const uno::Exception &) {
414 throw lang::WrappedTargetRuntimeException(
415 "getAllParts: exception",
422 uno::Reference<rdf::XURI>
const & i_xPart,
423 uno::Reference<rdf::XURI>
const & i_xType)
425 if (!i_xPart.is() || !i_xType.is())
throw uno::RuntimeException();
427 const uno::Reference<container::XEnumeration> xEnum(
429 getURI<rdf::URIs::RDF_TYPE>(i_rImpl.
m_xContext),
432 return xEnum->hasMoreElements();
433 }
catch (
const uno::RuntimeException &) {
435 }
catch (
const uno::Exception &) {
437 throw lang::WrappedTargetRuntimeException(
438 "isPartOfType: exception",
443static ::std::vector<uno::Reference<rdf::XURI>>
445 const uno::Reference<rdf::XURI>& i_xType)
447 ::std::vector<uno::Reference<rdf::XURI>> ret;
450 const uno::Reference<container::XEnumeration> xEnum(
452 getURI<rdf::URIs::PKG_HASPART>(i_rImpl.
m_xContext),
455 while (xEnum->hasMoreElements())
458 if (!(xEnum->nextElement() >>= stmt))
460 throw uno::RuntimeException();
462 const uno::Reference<rdf::XURI> xPart(stmt.Object, uno::UNO_QUERY);
466 const uno::Reference<container::XEnumeration> xEnum2(
468 xPart, getURI<rdf::URIs::RDF_TYPE>(i_rImpl.
m_xContext), i_xType),
470 if (xEnum2->hasMoreElements())
471 ret.emplace_back(xPart);
475 catch (
const uno::RuntimeException&)
479 catch (
const uno::Exception& e)
481 throw lang::WrappedTargetRuntimeException(
"getAllParts: exception",
nullptr,
486static ucb::InteractiveAugmentedIOException
488 ucb::IOErrorCode
const i_ErrorCode,
489 OUString
const & i_rUri, OUString
const & i_rResource)
491 ucb::InteractiveAugmentedIOException iaioe;
492 iaioe.Message = i_rMessage;
493 iaioe.Classification = task::InteractionClassification_ERROR;
494 iaioe.Code = i_ErrorCode;
496 const beans::PropertyValue uriProp(
"Uri",
497 -1,
uno::Any(i_rUri),
static_cast<beans::PropertyState
>(0));
498 const beans::PropertyValue rnProp(
500 -1,
uno::Any(i_rResource),
static_cast<beans::PropertyState
>(0));
514handleError( ucb::InteractiveAugmentedIOException
const & i_rException,
515 const uno::Reference<task::XInteractionHandler> & i_xHandler)
517 if (!i_xHandler.is()) {
518 throw lang::WrappedTargetException(
519 "DocumentMetadataAccess::loadMetadataFromStorage: exception",
524 new ::comphelper::OInteractionRequest(
uno::Any(i_rException)) );
526 new ::comphelper::OInteractionRetry );
528 new ::comphelper::OInteractionApprove );
530 new ::comphelper::OInteractionAbort );
532 pRequest->addContinuation( pApprove );
533 pRequest->addContinuation( pAbort );
535 i_xHandler->handle( pRequest );
536 if (pRetry->wasSelected()) {
538 }
else if (pApprove->wasSelected()) {
541 OSL_ENSURE(pAbort->wasSelected(),
"no continuation selected?");
542 throw lang::WrappedTargetException(
543 "DocumentMetadataAccess::loadMetadataFromStorage: exception",
552 std::set< OUString > & o_rFiles)
560 if (i_xStorage->hasByName(
s_styles) &&
561 i_xStorage->isStreamElement(
s_styles))
565 }
catch (
const uno::Exception &) {
573 uno::Reference< embed::XStorage >
const & i_xStorage,
574 OUString
const & i_rPath,
575 OUString
const & i_rBaseURI)
580 if (!
splitPath(i_rPath, dir, rest))
throw uno::RuntimeException();
582 if (!i_xStorage->isStreamElement(i_rPath)) {
584 "readStream: is not a stream",
585 ucb::IOErrorCode_NO_FILE, i_rBaseURI + i_rPath, i_rPath);
587 const uno::Reference<io::XStream>
xStream(
588 i_xStorage->openStreamElement(i_rPath,
589 embed::ElementModes::READ), uno::UNO_SET_THROW);
590 const uno::Reference<io::XInputStream> xInStream(
591 xStream->getInputStream(), uno::UNO_SET_THROW );
592 const uno::Reference<rdf::XURI> xBaseURI(
593 rdf::URI::create(i_rImpl.
m_xContext, i_rBaseURI));
594 const uno::Reference<rdf::XURI> xURI(
596 i_rBaseURI, i_rPath));
598 xInStream, xURI, xBaseURI);
600 if (!i_xStorage->isStorageElement(dir)) {
602 "readStream: is not a directory",
603 ucb::IOErrorCode_NO_DIRECTORY, i_rBaseURI + dir, dir);
605 const uno::Reference<embed::XStorage> xDir(
606 i_xStorage->openStorageElement(dir,
607 embed::ElementModes::READ));
608 const uno::Reference< beans::XPropertySet > xDirProps(xDir,
609 uno::UNO_QUERY_THROW);
612 xDirProps->getPropertyValue(
616 SAL_WARN(
"sfx",
"readStream: refusing to recurse into embedded document");
619 }
catch (
const uno::Exception &) { }
620 readStream(i_rImpl, xDir, rest, i_rBaseURI+dir+
"/" );
622 }
catch (
const container::NoSuchElementException & e) {
623 throw mkException(e.Message, ucb::IOErrorCode_NOT_EXISTING_PATH,
624 i_rBaseURI + i_rPath, i_rPath);
625 }
catch (
const io::IOException & e) {
626 throw mkException(e.Message, ucb::IOErrorCode_CANT_READ,
627 i_rBaseURI + i_rPath, i_rPath);
628 }
catch (
const rdf::ParseException & e) {
629 throw mkException(e.Message, ucb::IOErrorCode_WRONG_FORMAT,
630 i_rBaseURI + i_rPath, i_rPath);
637 uno::Reference<embed::XStorage>
const & i_xStorage,
638 OUString
const & i_rBaseURI,
639 uno::Reference<task::XInteractionHandler>
const & i_xHandler,
640 const OUString& i_rPath)
644 readStream(i_rImpl, i_xStorage, i_rPath, i_rBaseURI);
645 }
catch (
const ucb::InteractiveAugmentedIOException & e) {
647 }
catch (
const uno::RuntimeException &) {
649 }
catch (
const uno::Exception &) {
651 throw lang::WrappedTargetRuntimeException(
652 "importFile: exception",
660 uno::Reference< embed::XStorage >
const & i_xStorage,
661 uno::Reference<rdf::XURI>
const & i_xGraphName,
662 OUString
const & i_rFileName,
663 OUString
const & i_rBaseURI)
665 const uno::Reference<io::XStream>
xStream(
666 i_xStorage->openStreamElement(i_rFileName,
667 embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE),
669 const uno::Reference< beans::XPropertySet > xStreamProps(
xStream,
671 if (xStreamProps.is()) {
672 xStreamProps->setPropertyValue(
674 uno::Any(OUString(
"application/rdf+xml")));
676 const uno::Reference<io::XOutputStream> xOutStream(
677 xStream->getOutputStream(), uno::UNO_SET_THROW );
678 const uno::Reference<rdf::XURI> xBaseURI(
679 rdf::URI::create(i_rImpl.
m_xContext, i_rBaseURI));
681 xOutStream, i_xGraphName, xBaseURI);
687 uno::Reference< embed::XStorage >
const & i_xStorage,
688 uno::Reference<rdf::XURI>
const & i_xGraphName,
689 OUString
const & i_rPath,
690 OUString
const & i_rBaseURI)
694 if (!
splitPath(i_rPath, dir, rest))
throw uno::RuntimeException();
697 exportStream(i_rImpl, i_xStorage, i_xGraphName, i_rPath,
700 const uno::Reference<embed::XStorage> xDir(
701 i_xStorage->openStorageElement(dir,
702 embed::ElementModes::WRITE));
703 const uno::Reference< beans::XPropertySet > xDirProps(xDir,
704 uno::UNO_QUERY_THROW);
707 xDirProps->getPropertyValue(
711 SAL_WARN(
"sfx",
"writeStream: refusing to recurse into embedded document");
714 }
catch (
const uno::Exception &) { }
715 writeStream(i_rImpl, xDir, i_xGraphName, rest, i_rBaseURI+dir+
"/");
716 uno::Reference<embed::XTransactedObject>
const xTransaction(
717 xDir, uno::UNO_QUERY);
718 if (xTransaction.is()) {
719 xTransaction->commit();
722 }
catch (
const uno::RuntimeException &) {
724 }
catch (
const io::IOException &) {
731 const uno::Reference< embed::XStorage > & i_xStorage,
732 const uno::Reference<rdf::XURI> & i_xBaseURI,
733 const uno::Reference<task::XInteractionHandler> & i_xHandler)
748 ucb::InteractiveAugmentedIOException iaioe;
751 const uno::Reference <rdf::XURI> xManifest(
755 }
catch (
const ucb::InteractiveAugmentedIOException & e) {
757 if (ucb::IOErrorCode_NOT_EXISTING_PATH != e.Code) {
761 }
catch (
const uno::Exception & e) {
766 const uno::Reference<rdf::XNamedGraph> xManifestGraph(
768 i_rImpl.
m_xManifest.set(xManifestGraph.is() ? xManifestGraph :
769 i_rImpl.
m_xRepository->createGraph(xManifest), uno::UNO_SET_THROW);
773 getURI<rdf::URIs::RDF_TYPE>(i_rImpl.
m_xContext),
774 getURI<rdf::URIs::PKG_DOCUMENT>(i_rImpl.
m_xContext));
776 OSL_ENSURE(i_rImpl.
m_xBaseURI.is(),
"base URI is null");
777 OSL_ENSURE(i_rImpl.
m_xRepository.is(),
"repository is null");
778 OSL_ENSURE(i_rImpl.
m_xManifest.is(),
"manifest is null");
781 throw lang::WrappedTargetRuntimeException(
782 "DocumentMetadataAccess::loadMetadataFromStorage: "
783 "exception",
nullptr, rterr);
801 getURI<rdf::URIs::RDF_TYPE>(i_rImpl.
m_xContext),
802 getURI<rdf::URIs::PKG_DOCUMENT>(i_rImpl.
m_xContext));
803 }
catch (
const uno::Exception &) {
805 throw lang::WrappedTargetRuntimeException(
806 "init: unexpected exception",
nullptr,
812 throw uno::RuntimeException();
815 throw uno::RuntimeException();
821 uno::Reference< uno::XComponentContext >
const & i_xContext,
823 :
m_pImpl(new DocumentMetadataAccess_Impl(i_xContext, i_rRegistrySupplier))
828DocumentMetadataAccess::DocumentMetadataAccess(
829 uno::Reference< uno::XComponentContext >
const & i_xContext,
831 OUString
const & i_rURI)
832 :
m_pImpl(new DocumentMetadataAccess_Impl(i_xContext, i_rRegistrySupplier))
834 OSL_ENSURE(!i_rURI.isEmpty(),
"DMA::DMA: no URI given!");
835 OSL_ENSURE(i_rURI.endsWith(
"/"),
"DMA::DMA: URI without / given!");
836 if (!i_rURI.endsWith(
"/"))
throw uno::RuntimeException();
837 m_pImpl->m_xBaseURI.set(rdf::URI::create(
m_pImpl->m_xContext, i_rURI));
838 m_pImpl->m_xRepository.set(rdf::Repository::create(
m_pImpl->m_xContext),
844 OSL_ENSURE(
m_pImpl->m_xBaseURI.is(),
"base URI is null");
845 OSL_ENSURE(
m_pImpl->m_xRepository.is(),
"repository is null");
846 OSL_ENSURE(
m_pImpl->m_xManifest.is(),
"manifest is null");
849DocumentMetadataAccess::~DocumentMetadataAccess()
854uno::Reference< rdf::XRepository > SAL_CALL
855DocumentMetadataAccess::getRDFRepository()
857 OSL_ENSURE(
m_pImpl->m_xRepository.is(),
"repository not initialized");
863DocumentMetadataAccess::getStringValue()
865 return m_pImpl->m_xBaseURI->getStringValue();
870DocumentMetadataAccess::getNamespace()
872 return m_pImpl->m_xBaseURI->getNamespace();
876DocumentMetadataAccess::getLocalName()
878 return m_pImpl->m_xBaseURI->getLocalName();
882uno::Reference< rdf::XMetadatable > SAL_CALL
883DocumentMetadataAccess::getElementByMetadataReference(
884 const css::beans::StringPair & i_rReference)
887 m_pImpl->m_rXmlIdRegistrySupplier.GetXmlIdRegistry() );
889 throw uno::RuntimeException(
890 "DocumentMetadataAccess::getElementByXmlId: no registry", *
this);
895uno::Reference< rdf::XMetadatable > SAL_CALL
896DocumentMetadataAccess::getElementByURI(
897 const uno::Reference< rdf::XURI > & i_xURI )
900 throw lang::IllegalArgumentException(
901 "DocumentMetadataAccess::getElementByURI: URI is null", *
this, 0);
904 const OUString baseURI(
m_pImpl->m_xBaseURI->getStringValue() );
905 const OUString
name( i_xURI->getStringValue() );
906 if (!
name.match(baseURI)) {
911 if (!
splitXmlId(
name.subView(baseURI.getLength()), path, idref)) {
915 return getElementByMetadataReference( beans::StringPair(path, idref) );
918uno::Sequence<uno::Reference<rdf::XURI>> SAL_CALL
919DocumentMetadataAccess::getMetadataGraphsWithType(
const uno::Reference<rdf::XURI>& i_xType)
923 throw lang::IllegalArgumentException(
"DocumentMetadataAccess::getMetadataGraphsWithType: "
931uno::Reference<rdf::XURI> SAL_CALL
932DocumentMetadataAccess::addMetadataFile(
const OUString & i_rFileName,
933 const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
936 throw lang::IllegalArgumentException(
937 "DocumentMetadataAccess::addMetadataFile: invalid FileName",
941 throw lang::IllegalArgumentException(
942 "DocumentMetadataAccess::addMetadataFile:"
943 "invalid FileName: reserved", *
this, 0);
945 if (std::any_of(i_rTypes.begin(), i_rTypes.end(),
946 [](
const uno::Reference< rdf::XURI >& rType) { return !rType.is(); })) {
947 throw lang::IllegalArgumentException(
948 "DocumentMetadataAccess::addMetadataFile: "
949 "null type", *
this, 2);
952 const uno::Reference<rdf::XURI> xGraphName(
956 m_pImpl->m_xRepository->createGraph(xGraphName);
957 }
catch (
const rdf::RepositoryException &) {
959 throw lang::WrappedTargetRuntimeException(
960 "DocumentMetadataAccess::addMetadataFile: exception",
969uno::Reference<rdf::XURI> SAL_CALL
970DocumentMetadataAccess::importMetadataFile(::sal_Int16 i_Format,
971 const uno::Reference< io::XInputStream > & i_xInStream,
972 const OUString & i_rFileName,
973 const uno::Reference< rdf::XURI > & i_xBaseURI,
974 const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
977 throw lang::IllegalArgumentException(
978 "DocumentMetadataAccess::importMetadataFile: invalid FileName",
982 throw lang::IllegalArgumentException(
983 "DocumentMetadataAccess::importMetadataFile:"
984 "invalid FileName: reserved", *
this, 0);
986 if (std::any_of(i_rTypes.begin(), i_rTypes.end(),
987 [](
const uno::Reference< rdf::XURI >& rType) { return !rType.is(); })) {
988 throw lang::IllegalArgumentException(
989 "DocumentMetadataAccess::importMetadataFile: null type",
993 const uno::Reference<rdf::XURI> xGraphName(
997 m_pImpl->m_xRepository->importGraph(
998 i_Format, i_xInStream, xGraphName, i_xBaseURI);
999 }
catch (
const rdf::RepositoryException &) {
1001 throw lang::WrappedTargetRuntimeException(
1002 "DocumentMetadataAccess::importMetadataFile: "
1003 "RepositoryException", *
this, anyEx);
1013DocumentMetadataAccess::removeMetadataFile(
1014 const uno::Reference< rdf::XURI > & i_xGraphName)
1017 m_pImpl->m_xRepository->destroyGraph(i_xGraphName);
1018 }
catch (
const rdf::RepositoryException &) {
1020 throw lang::WrappedTargetRuntimeException(
1021 "DocumentMetadataAccess::removeMetadataFile: "
1022 "RepositoryException", *
this, anyEx);
1031DocumentMetadataAccess::addContentOrStylesFile(
1032 const OUString & i_rFileName)
1035 throw lang::IllegalArgumentException(
1036 "DocumentMetadataAccess::addContentOrStylesFile: "
1037 "invalid FileName", *
this, 0);
1041 throw lang::IllegalArgumentException(
1042 "DocumentMetadataAccess::addContentOrStylesFile: "
1043 "invalid FileName: must end with content.xml or styles.xml",
1049DocumentMetadataAccess::removeContentOrStylesFile(
1050 const OUString & i_rFileName)
1053 throw lang::IllegalArgumentException(
1054 "DocumentMetadataAccess::removeContentOrStylesFile: "
1055 "invalid FileName", *
this, 0);
1059 const uno::Reference<rdf::XURI> xPart(
1061 const uno::Reference<container::XEnumeration> xEnum(
1063 getURI<rdf::URIs::PKG_HASPART>(
m_pImpl->m_xContext),
1065 uno::UNO_SET_THROW);
1066 if (!xEnum->hasMoreElements()) {
1067 throw container::NoSuchElementException(
1068 "DocumentMetadataAccess::removeContentOrStylesFile: "
1069 "cannot find stream in manifest graph: " + i_rFileName,
1076 }
catch (
const uno::RuntimeException &) {
1078 }
catch (
const uno::Exception &) {
1080 throw lang::WrappedTargetRuntimeException(
1081 "DocumentMetadataAccess::removeContentOrStylesFile: exception",
1086void SAL_CALL DocumentMetadataAccess::loadMetadataFromStorage(
1087 const uno::Reference< embed::XStorage > & i_xStorage,
1088 const uno::Reference<rdf::XURI> & i_xBaseURI,
1089 const uno::Reference<task::XInteractionHandler> & i_xHandler)
1091 if (!i_xStorage.is()) {
1092 throw lang::IllegalArgumentException(
1093 "DocumentMetadataAccess::loadMetadataFromStorage: "
1094 "storage is null", *
this, 0);
1096 if (!i_xBaseURI.is()) {
1097 throw lang::IllegalArgumentException(
1098 "DocumentMetadataAccess::loadMetadataFromStorage: "
1099 "base URI is null", *
this, 1);
1101 const OUString baseURI( i_xBaseURI->getStringValue());
1102 if (baseURI.indexOf(
'#') >= 0) {
1103 throw lang::IllegalArgumentException(
1104 "DocumentMetadataAccess::loadMetadataFromStorage: "
1105 "base URI not absolute", *
this, 1);
1107 if (!baseURI.endsWith(
"/")) {
1108 throw lang::IllegalArgumentException(
1109 "DocumentMetadataAccess::loadMetadataFromStorage: "
1110 "base URI does not end with slash", *
this, 1);
1115 std::set< OUString > StgFiles;
1118 std::vector< OUString > MfstMetadataFiles;
1121 const ::std::vector< uno::Reference< rdf::XURI > > parts(
1123 const uno::Reference<rdf::XURI>& xContentFile(
1124 getURI<rdf::URIs::ODF_CONTENTFILE>(
m_pImpl->m_xContext));
1125 const uno::Reference<rdf::XURI>& xStylesFile(
1126 getURI<rdf::URIs::ODF_STYLESFILE>(
m_pImpl->m_xContext));
1127 const uno::Reference<rdf::XURI>& xMetadataFile(
1128 getURI<rdf::URIs::PKG_METADATAFILE>(
m_pImpl->m_xContext));
1129 const sal_Int32 len( baseURI.getLength() );
1130 for (
const auto& rxPart : parts) {
1131 const OUString
name(rxPart->getStringValue());
1132 if (!
name.match(baseURI)) {
1133 SAL_WARN(
"sfx",
"loadMetadataFromStorage: graph not in document: " <<
name);
1136 const OUString relName(
name.copy(len) );
1138 SAL_WARN(
"sfx",
"loadMetadataFromStorage: found ourselves a recursive manifest!");
1142 StgFiles.erase(relName);
1145 const uno::Reference <rdf::XURI> xName(
1148 m_pImpl->m_xManifest->addStatement(xName,
1149 getURI<rdf::URIs::RDF_TYPE>(
m_pImpl->m_xContext),
1154 const uno::Reference <rdf::XURI> xName(
1157 m_pImpl->m_xManifest->addStatement(xName,
1158 getURI<rdf::URIs::RDF_TYPE>(
m_pImpl->m_xContext),
1162 SAL_WARN(
"sfx",
"loadMetadataFromStorage: reserved file name in manifest");
1165 MfstMetadataFiles.push_back(relName);
1171 }
catch (
const uno::RuntimeException &) {
1173 }
catch (
const uno::Exception &) {
1175 throw lang::WrappedTargetRuntimeException(
1176 "DocumentMetadataAccess::loadMetadataFromStorage: "
1177 "exception", *
this, anyEx);
1180 for (
const auto& aStgFile : StgFiles)
1183 for (
const auto& aMfstMetadataFile : MfstMetadataFiles)
1187void SAL_CALL DocumentMetadataAccess::storeMetadataToStorage(
1188 const uno::Reference< embed::XStorage > & i_xStorage)
1190 if (!i_xStorage.is()) {
1191 throw lang::IllegalArgumentException(
1192 "DocumentMetadataAccess::storeMetadataToStorage: "
1193 "storage is null", *
this, 0);
1197 const uno::Reference <rdf::XURI> xManifest(
1199 const OUString baseURI(
m_pImpl->m_xBaseURI->getStringValue() );
1202 }
catch (
const uno::RuntimeException &) {
1204 }
catch (
const io::IOException &) {
1206 throw lang::WrappedTargetException(
1207 "storeMetadataToStorage: IO exception", *
this, anyEx);
1208 }
catch (
const uno::Exception &) {
1210 throw lang::WrappedTargetRuntimeException(
1211 "storeMetadataToStorage: exception", *
this, anyEx);
1216 const uno::Sequence<uno::Reference<rdf::XURI> > graphs(
1217 m_pImpl->m_xRepository->getGraphNames());
1218 const sal_Int32 len( baseURI.getLength() );
1219 for (
const uno::Reference<rdf::XURI>& xName : graphs) {
1220 const OUString
name(xName->getStringValue());
1221 if (!
name.match(baseURI)) {
1222 SAL_WARN(
"sfx",
"storeMetadataToStorage: graph not in document: " <<
name);
1225 const OUString relName(
name.copy(len) );
1230 SAL_WARN(
"sfx",
"storeMetadataToStorage: invalid file name: " << relName);
1235 }
catch (
const uno::RuntimeException &) {
1237 }
catch (
const io::IOException &) {
1239 throw lang::WrappedTargetException(
1240 "storeMetadataToStorage: IO exception",
1242 }
catch (
const uno::Exception &) {
1244 throw lang::WrappedTargetRuntimeException(
1245 "storeMetadataToStorage: exception",
1249 }
catch (
const rdf::RepositoryException &) {
1251 throw lang::WrappedTargetRuntimeException(
1252 "storeMetadataToStorage: exception", *
this, anyEx);
1257DocumentMetadataAccess::loadMetadataFromMedium(
1258 const uno::Sequence< beans::PropertyValue > & i_rMedium)
1260 uno::Reference<io::XInputStream> xIn;
1266 if (
md.addInputStream()) {
1269 if (!xIn.is() &&
URL.isEmpty()) {
1270 throw lang::IllegalArgumentException(
1271 "DocumentMetadataAccess::loadMetadataFromMedium: "
1272 "invalid medium: no URL, no input stream", *
this, 0);
1274 uno::Reference<embed::XStorage> xStorage;
1281 URL, embed::ElementModes::READ,
m_pImpl->m_xContext);
1283 }
catch (
const uno::RuntimeException &) {
1285 }
catch (
const io::IOException &) {
1287 }
catch (
const uno::Exception &) {
1289 throw lang::WrappedTargetException(
1290 "DocumentMetadataAccess::loadMetadataFromMedium: "
1291 "exception", *
this, anyEx);
1293 if (!xStorage.is()) {
1294 throw uno::RuntimeException(
1295 "DocumentMetadataAccess::loadMetadataFromMedium: "
1296 "cannot get Storage", *
this);
1298 uno::Reference<rdf::XURI> xBaseURI;
1301 }
catch (
const uno::Exception &) {
1305 }
catch (
const uno::Exception &) {
1306 OSL_FAIL(
"cannot create base URI");
1309 uno::Reference<task::XInteractionHandler> xIH;
1311 loadMetadataFromStorage(xStorage, xBaseURI, xIH);
1315DocumentMetadataAccess::storeMetadataToMedium(
1316 const uno::Sequence< beans::PropertyValue > & i_rMedium)
1321 if (
URL.isEmpty()) {
1322 throw lang::IllegalArgumentException(
1323 "DocumentMetadataAccess::storeMetadataToMedium: "
1324 "invalid medium: no URL", *
this, 0);
1331 if (xStorage.is()) {
1335 URL, embed::ElementModes::WRITE,
m_pImpl->m_xContext);
1338 if (!xStorage.is()) {
1339 throw uno::RuntimeException(
1340 "DocumentMetadataAccess::storeMetadataToMedium: "
1341 "cannot get Storage", *
this);
1344 utl::MediaDescriptor::const_iterator iter
1346 if (iter !=
md.end()) {
1347 uno::Reference< beans::XPropertySet > xProps(xStorage,
1348 uno::UNO_QUERY_THROW);
1351 xProps->setPropertyValue(
1354 }
catch (
const uno::Exception &) { }
1356 storeMetadataToStorage(xStorage);
1361 const bool bOk = aMedium.
Commit();
1368 task::ErrorCodeIOException
ex(
1369 "DocumentMetadataAccess::storeMetadataToMedium Commit failed: " + nError.
toString(),
1370 uno::Reference< uno::XInterface >(), sal_uInt32(nError));
1371 throw lang::WrappedTargetException(OUString(), *
this,
COMPHELPER_DLLPUBLIC OUString toString() const
void Close(bool bInDestruction=false)
css::uno::Reference< css::embed::XStorage > GetOutputStorage()
static css::uno::Reference< css::embed::XStorage > GetStorageFromInputStream(const css::uno::Reference< css::io::XInputStream > &xStream, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
static css::uno::Reference< css::embed::XStorage > GetStorageFromURL2(const OUString &aURL, sal_Int32 nStorageMode, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
static bool IsValidZipEntryFileName(std::u16string_view aName, bool bSlashAllowed)
interface for getElementByMetadataReference; for use by sfx2::DocumentMetadataAccess
virtual css::uno::Reference< css::rdf::XMetadatable > GetElementByMetadataReference(const css::beans::StringPair &i_rXmlId) const =0
#define TOOLS_WARN_EXCEPTION(area, stream)
#define ERRCODE_IO_GENERAL
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
Any SAL_CALL getCaughtException()
constexpr sal_Int64 md(U i, U)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
static uno::Reference< rdf::XURI > const & getURI(uno::Reference< uno::XComponentContext > const &i_xContext)
static bool isPartOfType(struct DocumentMetadataAccess_Impl const &i_rImpl, uno::Reference< rdf::XURI > const &i_xPart, uno::Reference< rdf::XURI > const &i_xType)
bool isValidNCName(std::u16string_view i_rIdref)
is i_rIdref a valid NCName ?
static ::std::vector< uno::Reference< rdf::XURI > > getAllParts(struct DocumentMetadataAccess_Impl const &i_rImpl)
static void init(struct DocumentMetadataAccess_Impl &i_rImpl)
init Impl struct
constexpr OUStringLiteral s_styles
static void writeStream(struct DocumentMetadataAccess_Impl &i_rImpl, uno::Reference< embed::XStorage > const &i_xStorage, uno::Reference< rdf::XURI > const &i_xGraphName, OUString const &i_rPath, OUString const &i_rBaseURI)
write a metadata file to the storage
constexpr OUStringLiteral s_content
static void initLoading(struct DocumentMetadataAccess_Impl &i_rImpl, const uno::Reference< embed::XStorage > &i_xStorage, const uno::Reference< rdf::XURI > &i_xBaseURI, const uno::Reference< task::XInteractionHandler > &i_xHandler)
static bool splitPath(OUString const &i_rPath, OUString &o_rDir, OUString &o_rRest)
split a uri hierarchy into first segment and rest
static bool addContentOrStylesFileImpl(struct DocumentMetadataAccess_Impl const &i_rImpl, const OUString &i_rPath)
add content.xml or styles.xml to manifest
static uno::Reference< rdf::XURI > getURIForStream(struct DocumentMetadataAccess_Impl const &i_rImpl, OUString const &i_rPath)
static void readStream(struct DocumentMetadataAccess_Impl &i_rImpl, uno::Reference< embed::XStorage > const &i_xStorage, OUString const &i_rPath, OUString const &i_rBaseURI)
import a metadata file into repository
static bool splitXmlId(std::u16string_view i_XmlId, OUString &o_StreamName, OUString &o_Idref)
bool isValidXmlId(std::u16string_view i_rStreamName, std::u16string_view i_rIdref)
static void removeFile(struct DocumentMetadataAccess_Impl const &i_rImpl, uno::Reference< rdf::XURI > const &i_xPart)
remove a file from the manifest
static void addMetadataFileImpl(struct DocumentMetadataAccess_Impl const &i_rImpl, const OUString &i_rPath, const uno::Sequence< uno::Reference< rdf::XURI > > &i_rTypes)
add metadata file to manifest
static ::std::vector< uno::Reference< rdf::XURI > > getAllParts(struct DocumentMetadataAccess_Impl const &i_rImpl, const uno::Reference< rdf::XURI > &i_xType)
static void addFile(struct DocumentMetadataAccess_Impl const &i_rImpl, uno::Reference< rdf::XURI > const &i_xType, OUString const &i_rPath, const uno::Sequence< uno::Reference< rdf::XURI > > *i_pTypes)
add statements declaring i_xResource to be a file of type i_xType with path i_rPath to manifest,...
static void collectFilesFromStorage(uno::Reference< embed::XStorage > const &i_xStorage, std::set< OUString > &o_rFiles)
check if storage has content.xml/styles.xml; e.g.
static void importFile(struct DocumentMetadataAccess_Impl &i_rImpl, uno::Reference< embed::XStorage > const &i_xStorage, OUString const &i_rBaseURI, uno::Reference< task::XInteractionHandler > const &i_xHandler, const OUString &i_rPath)
import a metadata file into repository
static bool isStylesFile(std::u16string_view i_rPath)
uno::Reference< rdf::XURI > createBaseURI(uno::Reference< uno::XComponentContext > const &i_xContext, uno::Reference< frame::XModel > const &i_xModel, OUString const &i_rPkgURI, std::u16string_view i_rSubDocument)
static bool handleError(ucb::InteractiveAugmentedIOException const &i_rException, const uno::Reference< task::XInteractionHandler > &i_xHandler)
error handling policy.
static ucb::InteractiveAugmentedIOException mkException(OUString const &i_rMessage, ucb::IOErrorCode const i_ErrorCode, OUString const &i_rUri, OUString const &i_rResource)
constexpr OUStringLiteral s_manifest
static bool isFileNameValid(std::u16string_view i_rFileName)
would storing the file to a XStorage succeed?
static bool isReservedFile(std::u16string_view i_rPath)
static void exportStream(struct DocumentMetadataAccess_Impl const &i_rImpl, uno::Reference< embed::XStorage > const &i_xStorage, uno::Reference< rdf::XURI > const &i_xGraphName, OUString const &i_rFileName, OUString const &i_rBaseURI)
actually write a metadata file to the storage
static bool isContentFile(std::u16string_view i_rPath)