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 
25 using namespace com::sun::star;
26 
27 css::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 
41 css::uno::Sequence<uno::Reference<css::rdf::XURI>>
42 SwRDFHelper::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 
63 std::map<OUString, OUString>
64 SwRDFHelper::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 
92 std::map<OUString, OUString>
93 SwRDFHelper::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 
100 void 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 
123 bool 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 
131 void 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 
149 void 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 
174 void 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 
202 std::map<OUString, OUString> SwRDFHelper::getTextNodeStatements(const OUString& rType, SwTextNode& rTextNode)
203 {
204  uno::Reference<rdf::XResource> xTextNode(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY);
205  return getStatements(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), rType, xTextNode);
206 }
207 
208 void 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), uno::UNO_QUERY);
211  addStatement(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), rType, rPath, xSubject, rKey, rValue);
212 }
213 
214 void 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), uno::UNO_QUERY);
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 
231 void 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), uno::UNO_QUERY);
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: */
SwDocShell * GetDocShell()
Definition: doc.hxx:1348
static css::uno::Reference< css::text::XTextContent > CreateXParagraph(SwDoc &rDoc, SwTextNode *pTextNode, css::uno::Reference< css::text::XText > const &xParentText=nullptr, const sal_Int32 nSelStart=-1, const sal_Int32 nSelEnd=-1)
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 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 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.
css::uno::Reference< css::frame::XModel > GetBaseModel() const
SwDoc * GetDoc()
Definition: node.hxx:702
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 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
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
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
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
Reference< XComponentContext > getProcessComponentContext()
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 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 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 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