LibreOffice Module xmloff (master)  1
xmlbasicscript.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  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include "xmlbasicscript.hxx"
23 #include <sal/log.hxx>
24 #include <xmlscript/xmlns.h>
25 #include <xmloff/xmlnamespace.hxx>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
28 #include <com/sun/star/document/XEmbeddedScripts.hpp>
29 #include <com/sun/star/xml/sax/SAXException.hpp>
31 #include <tools/diagnose_ex.h>
32 
33 using namespace ::com::sun::star;
34 using namespace ::com::sun::star::lang;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::xml::sax;
37 using namespace ::xmloff::token;
38 
39 namespace xmloff
40 {
41 // BasicElementBase
42 
44  : SvXMLImportContext(rImport)
45 {
46 }
47 
48 bool BasicElementBase::getBoolAttr(bool* pRet, sal_Int32 nToken,
49  const Reference<XFastAttributeList>& xAttributes)
50 {
51  OUString aValue = xAttributes->getOptionalValue(nToken);
52  if (!aValue.isEmpty())
53  {
54  if (aValue == "true")
55  {
56  *pRet = true;
57  return true;
58  }
59  else if (aValue == "false")
60  {
61  *pRet = false;
62  return true;
63  }
64  else
65  {
66  throw xml::sax::SAXException(SvXMLImport::getNameFromToken(nToken)
67  + ": no boolean value (true|false)!",
68  Reference<XInterface>(), Any());
69  }
70  }
71  return false;
72 }
73 
74 // BasicLibrariesElement
75 
77  const css::uno::Reference<css::frame::XModel>& rxModel)
78  : BasicElementBase(rImport)
79 {
80  // try the XEmbeddedScripts interface
81  Reference<document::XEmbeddedScripts> xDocumentScripts(rxModel, UNO_QUERY_THROW);
82  m_xLibContainer.set(xDocumentScripts->getBasicLibraries().get());
83 
84  if (!m_xLibContainer.is())
85  {
86  // try the "BasicLibraries" property (old-style, for compatibility)
87  Reference<beans::XPropertySet> xPSet(rxModel, UNO_QUERY);
88  if (xPSet.is())
89  xPSet->getPropertyValue("BasicLibraries") >>= m_xLibContainer;
90  }
91 
92  SAL_WARN_IF(!m_xLibContainer.is(), "xmlscript.xmlflat",
93  "BasicImport::startRootElement: nowhere to import to!");
94 
95  if (!m_xLibContainer.is())
96  {
97  throw xml::sax::SAXException("nowhere to import to", Reference<XInterface>(), Any());
98  }
99 }
100 
101 // XElement
102 
103 Reference<XFastContextHandler>
105  const Reference<XFastAttributeList>& xAttributes)
106 {
107  if (!IsTokenInNamespace(nElement, XML_NAMESPACE_OOO))
108  {
109  throw xml::sax::SAXException("illegal namespace!", Reference<XInterface>(), Any());
110  }
111  else if ((nElement & TOKEN_MASK) == XML_LIBRARY_LINKED)
112  {
113  OUString aName = xAttributes->getValue(NAMESPACE_TOKEN(XML_NAMESPACE_OOO) | XML_NAME);
114 
115  OUString aStorageURL = xAttributes->getValue(XML_ELEMENT(XLINK, XML_HREF));
116 
117  bool bReadOnly = false;
118  getBoolAttr(&bReadOnly, NAMESPACE_TOKEN(XML_NAMESPACE_OOO) | XML_READONLY, xAttributes);
119 
120  if (m_xLibContainer.is())
121  {
122  try
123  {
125  m_xLibContainer->createLibraryLink(aName, aStorageURL, bReadOnly));
126  if (xLib.is())
127  return new BasicElementBase(GetImport());
128  }
129  catch (const container::ElementExistException&)
130  {
131  TOOLS_INFO_EXCEPTION("xmlscript.xmlflat",
132  "BasicLibrariesElement::startChildElement");
133  }
134  catch (const lang::IllegalArgumentException&)
135  {
136  TOOLS_INFO_EXCEPTION("xmlscript.xmlflat",
137  "BasicLibrariesElement::startChildElement");
138  }
139  }
140  }
141  else if ((nElement & TOKEN_MASK) == XML_LIBRARY_EMBEDDED)
142  {
143  // TODO: create password protected libraries
144 
145  OUString aName = xAttributes->getValue(NAMESPACE_TOKEN(XML_NAMESPACE_OOO) | XML_NAME);
146 
147  bool bReadOnly = false;
148  getBoolAttr(&bReadOnly, NAMESPACE_TOKEN(XML_NAMESPACE_OOO) | XML_READONLY, xAttributes);
149 
150  if (m_xLibContainer.is())
151  {
152  try
153  {
155  if (m_xLibContainer->hasByName(aName))
156  {
157  // Standard library
158  m_xLibContainer->getByName(aName) >>= xLib;
159  }
160  else
161  {
162  xLib.set(m_xLibContainer->createLibrary(aName));
163  }
164 
165  if (xLib.is())
167  bReadOnly);
168  }
169  catch (const lang::IllegalArgumentException&)
170  {
171  TOOLS_INFO_EXCEPTION("xmlscript.xmlflat",
172  "BasicLibrariesElement::startChildElement");
173  }
174  }
175  }
176  else
177  {
178  throw xml::sax::SAXException("expected library-linked or library-embedded element!",
179  Reference<XInterface>(), Any());
180  }
181 
182  return nullptr;
183 }
184 
185 // BasicEmbeddedLibraryElement
186 
188  SvXMLImport& rImport, const Reference<script::XLibraryContainer2>& rxLibContainer,
189  const OUString& rLibName, bool bReadOnly)
190  : BasicElementBase(rImport)
191  , m_xLibContainer(rxLibContainer)
192  , m_aLibName(rLibName)
193  , m_bReadOnly(bReadOnly)
194 {
195  try
196  {
197  if (m_xLibContainer.is() && m_xLibContainer->hasByName(m_aLibName))
198  m_xLibContainer->getByName(m_aLibName) >>= m_xLib;
199  }
200  catch (const lang::WrappedTargetException&)
201  {
202  TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicEmbeddedLibraryElement::CTOR:");
203  }
204 }
205 
207  sal_Int32 nElement, const Reference<XFastAttributeList>& xAttributes)
208 {
209  if (!IsTokenInNamespace(nElement, XML_NAMESPACE_OOO))
210  {
211  throw xml::sax::SAXException("illegal namespace!", Reference<XInterface>(), Any());
212  }
213  else if ((nElement & TOKEN_MASK) == XML_MODULE)
214  {
215  OUString aName = xAttributes->getValue(NAMESPACE_TOKEN(XML_NAMESPACE_OOO) | XML_NAME);
216 
217  if (m_xLib.is() && !aName.isEmpty())
218  return new BasicModuleElement(GetImport(), m_xLib, aName);
219  }
220  else
221  {
222  throw xml::sax::SAXException("expected module element!", Reference<XInterface>(), Any());
223  }
224 
225  return nullptr;
226 }
227 
229 {
230  if (m_xLibContainer.is() && m_xLibContainer->hasByName(m_aLibName) && m_bReadOnly)
231  m_xLibContainer->setLibraryReadOnly(m_aLibName, m_bReadOnly);
232 }
233 
234 // BasicModuleElement
235 
238  const OUString& rName)
239  : BasicElementBase(rImport)
240  , m_xLib(rxLib)
241  , m_aName(rName)
242 {
243 }
244 
245 Reference<XFastContextHandler>
247  const Reference<XFastAttributeList>& xAttributes)
248 {
249  // TODO: <byte-code>
250 
251  if (!IsTokenInNamespace(nElement, XML_NAMESPACE_OOO))
252  {
253  throw xml::sax::SAXException("illegal namespace!", Reference<XInterface>(), Any());
254  }
255  else if ((nElement & TOKEN_MASK) == XML_SOURCE_CODE)
256  {
257  // TODO: password protected libraries
258 
259  if (xAttributes.is())
260  {
261  if (m_xLib.is() && !m_aName.isEmpty())
263  }
264  }
265  else
266  {
267  throw xml::sax::SAXException("expected source-code element!", Reference<XInterface>(),
268  Any());
269  }
270 
271  return nullptr;
272 }
273 
274 // BasicSourceCodeElement
275 
278  const OUString& rName)
279  : BasicElementBase(rImport)
280  , m_xLib(rxLib)
281  , m_aName(rName)
282 {
283 }
284 
285 // XElement
286 
287 void BasicSourceCodeElement::characters(const OUString& rChars) { m_aBuffer.append(rChars); }
288 
290 {
291  try
292  {
293  if (m_xLib.is() && !m_aName.isEmpty())
294  {
295  Any aElement;
296  aElement <<= m_aBuffer.makeStringAndClear();
297  m_xLib->insertByName(m_aName, aElement);
298  }
299  }
300  catch (const container::ElementExistException&)
301  {
302  TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicSourceCodeElement::endElement");
303  }
304  catch (const lang::IllegalArgumentException&)
305  {
306  TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicSourceCodeElement::endElement");
307  }
308  catch (const lang::WrappedTargetException&)
309  {
310  TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicSourceCodeElement::endElement");
311  }
312 }
313 }
314 
315 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
BasicLibrariesElement(SvXMLImport &rImport, const css::uno::Reference< css::frame::XModel > &rxModel)
OUString m_aName
css::uno::Reference< css::script::XLibraryContainer2 > m_xLibContainer
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:56
constexpr sal_uInt16 XML_NAMESPACE_OOO
bool bReadOnly
css::uno::Reference< css::container::XNameContainer > m_xLib
static bool getBoolAttr(bool *pRet, sal_Int32 nToken, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttributes)
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
virtual void SAL_CALL characters(const OUString &rChars) override
This method is called for all characters that are contained in the current element.
css::uno::Reference< css::container::XNameContainer > m_xLib
BasicEmbeddedLibraryElement(SvXMLImport &rImport, const css::uno::Reference< css::script::XLibraryContainer2 > &rxLibContainer, const OUString &rLibName, bool bReadOnly)
BasicElementBase(SvXMLImport &rImport)
css::uno::Reference< css::script::XLibraryContainer2 > m_xLibContainer
css::uno::Reference< css::container::XNameContainer > m_xLib
static const OUString & getNameFromToken(sal_Int32 nToken)
Definition: xmlimp.cxx:1907
This class deliberately does not support XWeak, to improve performance when loading large documents...
Definition: xmlictxt.hxx:45
#define TOOLS_INFO_EXCEPTION(area, stream)
constexpr bool IsTokenInNamespace(sal_Int32 nToken, sal_uInt16 nNamespacePrefix)
Definition: xmlimp.hxx:103
#define SAL_WARN_IF(condition, area, stream)
Handling of tokens in XML:
OUString aName
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:96
constexpr sal_Int32 NAMESPACE_TOKEN(sal_uInt16 prefixToken)
Definition: xmlimp.hxx:98
bool m_bReadOnly
BasicSourceCodeElement(SvXMLImport &rImport, const css::uno::Reference< css::container::XNameContainer > &rxLib, const OUString &rName)
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
constexpr sal_Int32 TOKEN_MASK
Definition: xmlimp.hxx:93
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
BasicModuleElement(SvXMLImport &rImport, const css::uno::Reference< css::container::XNameContainer > &rxLib, const OUString &rName)
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override