LibreOffice Module sw (master) 1
rdfhelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <rdfhelper.hxx>
11
12#include <com/sun/star/frame/XModel.hpp>
13#include <com/sun/star/rdf/Literal.hpp>
14#include <com/sun/star/rdf/Statement.hpp>
15#include <com/sun/star/rdf/URI.hpp>
16#include <com/sun/star/rdf/XDocumentMetadataAccess.hpp>
17
19
20#include <doc.hxx>
21#include <docsh.hxx>
22#include <ndtxt.hxx>
23#include <unoparagraph.hxx>
24
25using namespace com::sun::star;
26
27css::uno::Sequence<css::uno::Reference<css::rdf::XURI>> SwRDFHelper::getGraphNames(
28 const css::uno::Reference<rdf::XDocumentMetadataAccess>& xDocumentMetadataAccess,
29 const css::uno::Reference<rdf::XURI>& xType)
30{
31 try
32 {
33 return xDocumentMetadataAccess->getMetadataGraphsWithType(xType);
34 }
35 catch (const uno::RuntimeException&)
36 {
37 return uno::Sequence<uno::Reference<rdf::XURI>>();
38 }
39}
40
41css::uno::Sequence<uno::Reference<css::rdf::XURI>>
42SwRDFHelper::getGraphNames(const css::uno::Reference<css::frame::XModel>& xModel,
43 const OUString& rType)
44{
45 try
46 {
47 uno::Reference<uno::XComponentContext> xComponentContext(
49 // rdf::URI::create may fail with type: com.sun.star.uno.DeploymentException
50 // message: component context fails to supply service com.sun.star.rdf.URI of type com.sun.star.rdf.XURI
51 // context: cppu::ComponentContext
52 uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
53 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel,
54 uno::UNO_QUERY);
55 return getGraphNames(xDocumentMetadataAccess, xType);
56 }
57 catch (const ::css::uno::Exception&)
58 {
59 return uno::Sequence<uno::Reference<rdf::XURI>>();
60 }
61}
62
63std::map<OUString, OUString>
64SwRDFHelper::getStatements(const css::uno::Reference<css::frame::XModel>& xModel,
65 const uno::Sequence<uno::Reference<css::rdf::XURI>>& rGraphNames,
66 const css::uno::Reference<css::rdf::XResource>& xSubject)
67{
68 std::map<OUString, OUString> aRet;
69 if (!rGraphNames.hasElements())
70 return aRet;
71
72 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
73 const uno::Reference<rdf::XRepository>& xRepo = xDocumentMetadataAccess->getRDFRepository();
74 for (const uno::Reference<rdf::XURI>& xGraphName : rGraphNames)
75 {
76 uno::Reference<rdf::XNamedGraph> xGraph = xRepo->getGraph(xGraphName);
77 if (!xGraph.is())
78 continue;
79
80 uno::Reference<container::XEnumeration> xStatements = xGraph->getStatements(
81 xSubject, uno::Reference<rdf::XURI>(), uno::Reference<rdf::XURI>());
82 while (xStatements->hasMoreElements())
83 {
84 const rdf::Statement aStatement = xStatements->nextElement().get<rdf::Statement>();
85 aRet[aStatement.Predicate->getStringValue()] = aStatement.Object->getStringValue();
86 }
87 }
88
89 return aRet;
90}
91
92std::map<OUString, OUString>
93SwRDFHelper::getStatements(const css::uno::Reference<css::frame::XModel>& xModel,
94 const OUString& rType,
95 const css::uno::Reference<css::rdf::XResource>& xSubject)
96{
97 return getStatements(xModel, getGraphNames(xModel, rType), xSubject);
98}
99
100void SwRDFHelper::addStatement(const css::uno::Reference<css::frame::XModel>& xModel,
101 const OUString& rType, const OUString& rPath,
102 const css::uno::Reference<css::rdf::XResource>& xSubject,
103 const OUString& rKey, const OUString& rValue)
104{
105 uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
106 uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
107 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
108 const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
109 uno::Reference<rdf::XURI> xGraphName;
110 if (aGraphNames.hasElements())
111 xGraphName = aGraphNames[0];
112 else
113 {
114 uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType };
115 xGraphName = xDocumentMetadataAccess->addMetadataFile(rPath, xTypes);
116 }
117 uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
118 uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
119 uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, rValue);
120 xGraph->addStatement(xSubject, xKey, xValue);
121}
122
123bool SwRDFHelper::hasMetadataGraph(const css::uno::Reference<css::frame::XModel>& xModel, const OUString& rType)
124{
125 uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
126 uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
127 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
128 return getGraphNames(xDocumentMetadataAccess, xType).hasElements();
129}
130
131void SwRDFHelper::removeStatement(const css::uno::Reference<css::frame::XModel>& xModel,
132 const OUString& rType,
133 const css::uno::Reference<css::rdf::XResource>& xSubject,
134 const OUString& rKey, const OUString& rValue)
135{
136 uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
137 uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
138 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
139 const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
140 if (!aGraphNames.hasElements())
141 return;
142
143 uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(aGraphNames[0]);
144 uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
145 uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, rValue);
146 xGraph->removeStatements(xSubject, xKey, xValue);
147}
148
149void SwRDFHelper::clearStatements(const css::uno::Reference<css::frame::XModel>& xModel,
150 const OUString& rType,
151 const css::uno::Reference<css::rdf::XResource>& xSubject)
152{
153 uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
154 uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
155 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
156 const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
157 if (!aGraphNames.hasElements())
158 return;
159
160 for (const uno::Reference<rdf::XURI>& xGraphName : aGraphNames)
161 {
162 uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
163 uno::Reference<container::XEnumeration> xStatements = xGraph->getStatements(xSubject, uno::Reference<rdf::XURI>(), uno::Reference<rdf::XURI>());
164 while (xStatements->hasMoreElements())
165 {
166 rdf::Statement aStatement = xStatements->nextElement().get<rdf::Statement>();
167 uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, aStatement.Predicate->getStringValue());
168 uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, aStatement.Object->getStringValue());
169 xGraph->removeStatements(xSubject, xKey, xValue);
170 }
171 }
172}
173
174void SwRDFHelper::cloneStatements(const css::uno::Reference<css::frame::XModel>& xSrcModel,
175 const css::uno::Reference<css::frame::XModel>& xDstModel,
176 const OUString& rType,
177 const css::uno::Reference<css::rdf::XResource>& xSrcSubject,
178 const css::uno::Reference<css::rdf::XResource>& xDstSubject)
179{
180 uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
181 uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
182 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xSrcModel, uno::UNO_QUERY);
183 const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
184 if (!aGraphNames.hasElements())
185 return;
186
187 for (const uno::Reference<rdf::XURI>& xGraphName : aGraphNames)
188 {
189 uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
190 uno::Reference<container::XEnumeration> xStatements = xGraph->getStatements(xSrcSubject, uno::Reference<rdf::XURI>(), uno::Reference<rdf::XURI>());
191 while (xStatements->hasMoreElements())
192 {
193 const rdf::Statement aStatement = xStatements->nextElement().get<rdf::Statement>();
194
195 const OUString sKey = aStatement.Predicate->getStringValue();
196 const OUString sValue = aStatement.Object->getStringValue();
197 addStatement(xDstModel, rType, xGraphName->getLocalName(), xDstSubject, sKey, sValue);
198 }
199 }
200}
201
202std::map<OUString, OUString> SwRDFHelper::getTextNodeStatements(const OUString& rType, SwTextNode& rTextNode)
203{
204 uno::Reference<rdf::XResource> xTextNode(SwXParagraph::CreateXParagraph(rTextNode.GetDoc(), &rTextNode));
205 return getStatements(rTextNode.GetDoc().GetDocShell()->GetBaseModel(), rType, xTextNode);
206}
207
208void SwRDFHelper::addTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue)
209{
210 uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(rTextNode.GetDoc(), &rTextNode));
211 addStatement(rTextNode.GetDoc().GetDocShell()->GetBaseModel(), rType, rPath, xSubject, rKey, rValue);
212}
213
214void SwRDFHelper::removeTextNodeStatement(const OUString& rType, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue)
215{
216 uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
217 uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
218 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(rTextNode.GetDoc().GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
219 const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
220 if (!aGraphNames.hasElements())
221 return;
222
223 uno::Reference<rdf::XURI> xGraphName = aGraphNames[0];
224 uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
225 uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(rTextNode.GetDoc(), &rTextNode));
226 uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
227 uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, rValue);
228 xGraph->removeStatements(xSubject, xKey, xValue);
229}
230
231void SwRDFHelper::updateTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rOldValue, const OUString& rNewValue)
232{
233 uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
234 uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
235 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(rTextNode.GetDoc().GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
236 const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
237 uno::Reference<rdf::XURI> xGraphName;
238 if (aGraphNames.hasElements())
239 {
240 xGraphName = aGraphNames[0];
241 }
242 else
243 {
244 uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType };
245 xGraphName = xDocumentMetadataAccess->addMetadataFile(rPath, xTypes);
246 }
247
248 uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
249 uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(rTextNode.GetDoc(), &rTextNode));
250 uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
251
252 if (aGraphNames.hasElements())
253 {
254 // Remove the old value.
255 uno::Reference<rdf::XLiteral> xOldValue = rdf::Literal::create(xComponentContext, rOldValue);
256 xGraph->removeStatements(xSubject, xKey, xOldValue);
257 }
258
259 // Now add it with new value.
260 uno::Reference<rdf::XLiteral> xNewValue = rdf::Literal::create(xComponentContext, rNewValue);
261 xGraph->addStatement(xSubject, xKey, xNewValue);
262}
263
264/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
SwDoc & GetDoc()
Definition: node.hxx:233
static void removeTextNodeStatement(const OUString &rType, SwTextNode &rTextNode, const OUString &rKey, const OUString &rValue)
Remove an (rTextNode, key, value) statement in the graph of type rType.
Definition: rdfhelper.cxx:214
static void removeStatement(const css::uno::Reference< css::frame::XModel > &xModel, const OUString &rType, const css::uno::Reference< css::rdf::XResource > &xSubject, const OUString &rKey, const OUString &rValue)
Remove an (XResource, key, value) statement in the graph of type rType, if it exists.
Definition: rdfhelper.cxx:131
static std::map< OUString, OUString > getStatements(const css::uno::Reference< css::frame::XModel > &xModel, const css::uno::Sequence< css::uno::Reference< css::rdf::XURI > > &rGraphNames, const css::uno::Reference< css::rdf::XResource > &xSubject)
Gets all (XResource, key, value) statements in RDF graphs given the graph-names.
static void clearStatements(const css::uno::Reference< css::frame::XModel > &xModel, const OUString &rType, const css::uno::Reference< css::rdf::XResource > &xSubject)
Remove all statements in the graph of type rType, if any exists.
Definition: rdfhelper.cxx:149
static void addStatement(const css::uno::Reference< css::frame::XModel > &xModel, const OUString &rType, const OUString &rPath, const css::uno::Reference< css::rdf::XResource > &xSubject, const OUString &rKey, const OUString &rValue)
Add an (XResource, key, value) statement in the graph of type rType – or if it does not exist,...
Definition: rdfhelper.cxx:100
static void updateTextNodeStatement(const OUString &rType, const OUString &rPath, SwTextNode &rTextNode, const OUString &rKey, const OUString &rOldValue, const OUString &rNewValue)
Update an (rTextNode, key, value) statement in the graph of type rType from old value to new....
Definition: rdfhelper.cxx:231
static void cloneStatements(const css::uno::Reference< css::frame::XModel > &xSrcModel, const css::uno::Reference< css::frame::XModel > &xDstModel, const OUString &rType, const css::uno::Reference< css::rdf::XResource > &xSrcSubject, const css::uno::Reference< css::rdf::XResource > &xDstSubject)
Clone all statements in the graph of type rType, if any exists, from one subject to another.
Definition: rdfhelper.cxx:174
static css::uno::Sequence< css::uno::Reference< css::rdf::XURI > > getGraphNames(const css::uno::Reference< css::rdf::XDocumentMetadataAccess > &xDocumentMetadataAccess, const css::uno::Reference< css::rdf::XURI > &xType)
Gets all graph-names in RDF of a given type.
static void addTextNodeStatement(const OUString &rType, const OUString &rPath, SwTextNode &rTextNode, const OUString &rKey, const OUString &rValue)
Add an (rTextNode, key, value) statement in the graph of type rType – or if it does not exist,...
Definition: rdfhelper.cxx:208
static bool hasMetadataGraph(const css::uno::Reference< css::frame::XModel > &xModel, const OUString &rType)
Check if a graph of type rType exists.
Definition: rdfhelper.cxx:123
static std::map< OUString, OUString > getTextNodeStatements(const OUString &rType, SwTextNode &rTextNode)
Gets all (rTextNode, key, value) statements in RDF graphs of type rType.
Definition: rdfhelper.cxx:202
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
static rtl::Reference< SwXParagraph > CreateXParagraph(SwDoc &rDoc, SwTextNode *pTextNode, css::uno::Reference< css::text::XText > const &xParentText=nullptr, const sal_Int32 nSelStart=-1, const sal_Int32 nSelEnd=- 1)
Reference< XComponentContext > getProcessComponentContext()
Reference< XModel > xModel