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/rdf/Literal.hpp>
13 #include <com/sun/star/rdf/Statement.hpp>
14 #include <com/sun/star/rdf/URI.hpp>
15 #include <com/sun/star/rdf/XDocumentMetadataAccess.hpp>
16 
18 
19 #include <doc.hxx>
20 #include <docsh.hxx>
21 #include <ndtxt.hxx>
22 #include <unoparagraph.hxx>
23 
24 using namespace com::sun::star;
25 
26 css::uno::Sequence<css::uno::Reference<css::rdf::XURI>> SwRDFHelper::getGraphNames(
27  const css::uno::Reference<rdf::XDocumentMetadataAccess>& xDocumentMetadataAccess,
28  const css::uno::Reference<rdf::XURI>& xType)
29 {
30  try
31  {
32  return xDocumentMetadataAccess->getMetadataGraphsWithType(xType);
33  }
34  catch (const uno::RuntimeException&)
35  {
36  return uno::Sequence<uno::Reference<rdf::XURI>>();
37  }
38 }
39 
40 css::uno::Sequence<uno::Reference<css::rdf::XURI>>
41 SwRDFHelper::getGraphNames(const css::uno::Reference<css::frame::XModel>& xModel,
42  const OUString& rType)
43 {
44  try
45  {
46  uno::Reference<uno::XComponentContext> xComponentContext(
48  // rdf::URI::create may fail with type: com.sun.star.uno.DeploymentException
49  // message: component context fails to supply service com.sun.star.rdf.URI of type com.sun.star.rdf.XURI
50  // context: cppu::ComponentContext
51  uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
52  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel,
53  uno::UNO_QUERY);
54  return getGraphNames(xDocumentMetadataAccess, xType);
55  }
56  catch (const ::css::uno::Exception&)
57  {
58  return uno::Sequence<uno::Reference<rdf::XURI>>();
59  }
60 }
61 
62 std::map<OUString, OUString>
63 SwRDFHelper::getStatements(const css::uno::Reference<css::frame::XModel>& xModel,
64  const uno::Sequence<uno::Reference<css::rdf::XURI>>& rGraphNames,
65  const css::uno::Reference<css::rdf::XResource>& xSubject)
66 {
67  std::map<OUString, OUString> aRet;
68  if (!rGraphNames.hasElements())
69  return aRet;
70 
71  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
72  const uno::Reference<rdf::XRepository>& xRepo = xDocumentMetadataAccess->getRDFRepository();
73  for (const uno::Reference<rdf::XURI>& xGraphName : rGraphNames)
74  {
75  uno::Reference<rdf::XNamedGraph> xGraph = xRepo->getGraph(xGraphName);
76  if (!xGraph.is())
77  continue;
78 
79  uno::Reference<container::XEnumeration> xStatements = xGraph->getStatements(
80  xSubject, uno::Reference<rdf::XURI>(), uno::Reference<rdf::XURI>());
81  while (xStatements->hasMoreElements())
82  {
83  const rdf::Statement aStatement = xStatements->nextElement().get<rdf::Statement>();
84  aRet[aStatement.Predicate->getStringValue()] = aStatement.Object->getStringValue();
85  }
86  }
87 
88  return aRet;
89 }
90 
91 std::map<OUString, OUString>
92 SwRDFHelper::getStatements(const css::uno::Reference<css::frame::XModel>& xModel,
93  const OUString& rType,
94  const css::uno::Reference<css::rdf::XResource>& xSubject)
95 {
96  return getStatements(xModel, getGraphNames(xModel, rType), xSubject);
97 }
98 
99 void SwRDFHelper::addStatement(const css::uno::Reference<css::frame::XModel>& xModel,
100  const OUString& rType, const OUString& rPath,
101  const css::uno::Reference<css::rdf::XResource>& xSubject,
102  const OUString& rKey, const OUString& rValue)
103 {
104  uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
105  uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
106  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
107  const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
108  uno::Reference<rdf::XURI> xGraphName;
109  if (aGraphNames.hasElements())
110  xGraphName = aGraphNames[0];
111  else
112  {
113  uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType };
114  xGraphName = xDocumentMetadataAccess->addMetadataFile(rPath, xTypes);
115  }
116  uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
117  uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
118  uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, rValue);
119  xGraph->addStatement(xSubject, xKey, xValue);
120 }
121 
122 bool SwRDFHelper::hasMetadataGraph(const css::uno::Reference<css::frame::XModel>& xModel, const OUString& rType)
123 {
124  uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
125  uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
126  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
127  return getGraphNames(xDocumentMetadataAccess, xType).hasElements();
128 }
129 
130 void SwRDFHelper::removeStatement(const css::uno::Reference<css::frame::XModel>& xModel,
131  const OUString& rType,
132  const css::uno::Reference<css::rdf::XResource>& xSubject,
133  const OUString& rKey, const OUString& rValue)
134 {
135  uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
136  uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
137  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
138  const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
139  if (!aGraphNames.hasElements())
140  return;
141 
142  uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(aGraphNames[0]);
143  uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
144  uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, rValue);
145  xGraph->removeStatements(xSubject, xKey, xValue);
146 }
147 
148 void SwRDFHelper::clearStatements(const css::uno::Reference<css::frame::XModel>& xModel,
149  const OUString& rType,
150  const css::uno::Reference<css::rdf::XResource>& xSubject)
151 {
152  uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
153  uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
154  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
155  const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
156  if (!aGraphNames.hasElements())
157  return;
158 
159  for (const uno::Reference<rdf::XURI>& xGraphName : aGraphNames)
160  {
161  uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
162  uno::Reference<container::XEnumeration> xStatements = xGraph->getStatements(xSubject, uno::Reference<rdf::XURI>(), uno::Reference<rdf::XURI>());
163  while (xStatements->hasMoreElements())
164  {
165  rdf::Statement aStatement = xStatements->nextElement().get<rdf::Statement>();
166  uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, aStatement.Predicate->getStringValue());
167  uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, aStatement.Object->getStringValue());
168  xGraph->removeStatements(xSubject, xKey, xValue);
169  }
170  }
171 }
172 
173 void SwRDFHelper::cloneStatements(const css::uno::Reference<css::frame::XModel>& xSrcModel,
174  const css::uno::Reference<css::frame::XModel>& xDstModel,
175  const OUString& rType,
176  const css::uno::Reference<css::rdf::XResource>& xSrcSubject,
177  const css::uno::Reference<css::rdf::XResource>& xDstSubject)
178 {
179  uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
180  uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
181  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xSrcModel, uno::UNO_QUERY);
182  const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
183  if (!aGraphNames.hasElements())
184  return;
185 
186  for (const uno::Reference<rdf::XURI>& xGraphName : aGraphNames)
187  {
188  uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
189  uno::Reference<container::XEnumeration> xStatements = xGraph->getStatements(xSrcSubject, uno::Reference<rdf::XURI>(), uno::Reference<rdf::XURI>());
190  while (xStatements->hasMoreElements())
191  {
192  const rdf::Statement aStatement = xStatements->nextElement().get<rdf::Statement>();
193 
194  const OUString sKey = aStatement.Predicate->getStringValue();
195  const OUString sValue = aStatement.Object->getStringValue();
196  addStatement(xDstModel, rType, xGraphName->getLocalName(), xDstSubject, sKey, sValue);
197  }
198  }
199 }
200 
201 std::map<OUString, OUString> SwRDFHelper::getTextNodeStatements(const OUString& rType, SwTextNode& rTextNode)
202 {
203  uno::Reference<rdf::XResource> xTextNode(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY);
204  return getStatements(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), rType, xTextNode);
205 }
206 
207 void SwRDFHelper::addTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue)
208 {
209  uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY);
210  addStatement(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), rType, rPath, xSubject, rKey, rValue);
211 }
212 
213 void SwRDFHelper::removeTextNodeStatement(const OUString& rType, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue)
214 {
215  uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
216  uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
217  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
218  const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
219  if (!aGraphNames.hasElements())
220  return;
221 
222  uno::Reference<rdf::XURI> xGraphName = aGraphNames[0];
223  uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
224  uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY);
225  uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
226  uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, rValue);
227  xGraph->removeStatements(xSubject, xKey, xValue);
228 }
229 
230 void SwRDFHelper::updateTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rOldValue, const OUString& rNewValue)
231 {
232  uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
233  uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
234  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
235  const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = getGraphNames(xDocumentMetadataAccess, xType);
236  uno::Reference<rdf::XURI> xGraphName;
237  if (aGraphNames.hasElements())
238  {
239  xGraphName = aGraphNames[0];
240  }
241  else
242  {
243  uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType };
244  xGraphName = xDocumentMetadataAccess->addMetadataFile(rPath, xTypes);
245  }
246 
247  uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
248  uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY);
249  uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
250 
251  if (aGraphNames.hasElements())
252  {
253  // Remove the old value.
254  uno::Reference<rdf::XLiteral> xOldValue = rdf::Literal::create(xComponentContext, rOldValue);
255  xGraph->removeStatements(xSubject, xKey, xOldValue);
256  }
257 
258  // Now add it with new value.
259  uno::Reference<rdf::XLiteral> xNewValue = rdf::Literal::create(xComponentContext, rNewValue);
260  xGraph->addStatement(xSubject, xKey, xNewValue);
261 }
262 
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwDocShell * GetDocShell()
Definition: doc.hxx:1342
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:173
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:230
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:207
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:213
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
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:201
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:130
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:99
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:148
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:122