update dev300-m58
[ooovba.git] / configmgr / source / xml / layerwriter.cxx
blob8c47d0164f4d69ec68eb07ecef2a9bb11a9b4191
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: layerwriter.cxx,v $
10 * $Revision: 1.15 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
34 #include "layerwriter.hxx"
36 #ifndef CONFIGMGR_API_FACTORY_HXX_
37 #include "confapifactory.hxx"
38 #endif
39 #include "valueformatter.hxx"
40 #include <com/sun/star/beans/IllegalTypeException.hpp>
41 #include <com/sun/star/configuration/backend/BackendAccessException.hpp>
42 #include <com/sun/star/configuration/backend/ConnectionLostException.hpp>
43 #include <com/sun/star/configuration/backend/NodeAttribute.hpp>
44 // -----------------------------------------------------------------------------
46 namespace configmgr
48 // -----------------------------------------------------------------------------
49 namespace xml
51 // -----------------------------------------------------------------------------
52 namespace uno = ::com::sun::star::uno;
53 namespace io = ::com::sun::star::io;
54 namespace sax = ::com::sun::star::xml::sax;
55 // -----------------------------------------------------------------------------
57 uno::Reference< uno::XInterface > SAL_CALL instantiateLayerWriter
58 ( uno::Reference< uno::XComponentContext > const& xContext )
60 return * new LayerWriter(xContext);
62 // -----------------------------------------------------------------------------
64 namespace
66 static inline
67 uno::Reference< script::XTypeConverter > createTCV(uno::Reference< lang::XMultiServiceFactory > const & _xSvcFactory)
69 OSL_ENSURE(_xSvcFactory.is(),"Cannot create Write Formatter without a ServiceManager");
71 static const rtl::OUString k_sTCVService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter"));
73 return uno::Reference< script::XTypeConverter >::query(_xSvcFactory->createInstance(k_sTCVService));
75 // -----------------------------------------------------------------------------
76 static
77 void translateSAXException( sax::SAXException & aSAXException,
78 backenduno::XLayerHandler * context)
80 rtl::OUString sMessage = aSAXException.Message;
82 uno::Any const & aWrappedException = aSAXException.WrappedException;
83 if (aWrappedException.hasValue())
85 if (aWrappedException.getValueTypeClass() != uno::TypeClass_EXCEPTION)
86 OSL_ENSURE(false, "ERROR: WrappedException is not an exception");
88 else if (sMessage.getLength() == 0)
89 sMessage = static_cast<uno::Exception const *>(aWrappedException.getValue())->Message;
91 // assume that a SAXException with WrappedException indicates a storage access error
92 throw backenduno::BackendAccessException(sMessage,context,aWrappedException);
94 else
96 // assume that a SAXException without WrappedException indicates non-well-formed data
97 throw backenduno::MalformedDataException(sMessage,context,uno::makeAny(aSAXException));
100 // -----------------------------------------------------------------------------
101 static inline uno::Type getIOExceptionType()
103 io::IOException const * const ioexception = 0;
104 return ::getCppuType(ioexception);
106 static inline uno::Type getNotConnectedExceptionType()
108 io::NotConnectedException const * const ncexception = 0;
109 return ::getCppuType(ncexception);
111 static
112 void translateIOException(uno::Any const & anIOException,
113 backenduno::XLayerHandler * context)
115 OSL_ASSERT(anIOException.isExtractableTo(getIOExceptionType()));
116 io::IOException const * pException = static_cast<io::IOException const *>(anIOException.getValue());
117 rtl::OUString sMessage = pException->Message;
119 if (anIOException.isExtractableTo(getNotConnectedExceptionType()))
121 throw backenduno::ConnectionLostException(sMessage,context,anIOException);
123 else
125 throw backenduno::BackendAccessException(sMessage,context,anIOException);
128 // -----------------------------------------------------------------------------
130 // -----------------------------------------------------------------------------
132 LayerWriter::LayerWriter(uno::Reference< uno::XComponentContext > const & _xContext)
133 : WriterService< ::com::sun::star::configuration::backend::XLayerHandler >(_xContext)
134 , m_xTCV( createTCV( WriterService< ::com::sun::star::configuration::backend::XLayerHandler >::getServiceFactory() ) )
135 , m_bInProperty(false)
136 , m_bStartedDocument(false)
139 // -----------------------------------------------------------------------------
141 LayerWriter::~LayerWriter()
144 // -----------------------------------------------------------------------------
146 void SAL_CALL LayerWriter::startLayer( )
147 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
148 uno::RuntimeException)
150 m_aFormatter.reset();
151 m_bInProperty = false;
152 m_bStartedDocument = false;
154 checkInElement(false);
156 // -----------------------------------------------------------------------------
158 void SAL_CALL LayerWriter::endLayer( )
159 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
160 uno::RuntimeException)
162 checkInElement(false);
165 if (!m_bStartedDocument)
167 uno::Reference< io::XOutputStream > aStream = this->getOutputStream( );
168 aStream->closeOutput();
170 else
172 getWriteHandler()->endDocument();
173 m_aFormatter.reset();
174 m_bStartedDocument = false;
177 catch (sax::SAXException & xe) { translateSAXException(xe,this); }
178 catch (io::NotConnectedException & ioe) { translateIOException(uno::makeAny(ioe),this); }
179 catch (io::BufferSizeExceededException & ioe) { translateIOException(uno::makeAny(ioe),this); }
180 catch (io::IOException & ioe) { translateIOException(uno::makeAny(ioe),this); }
182 // -----------------------------------------------------------------------------
184 void SAL_CALL LayerWriter::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
185 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
186 uno::RuntimeException)
190 if (!m_bStartedDocument)
192 getWriteHandler()->startDocument();
193 m_bStartedDocument = true;
195 ElementInfo aInfo(aName, this->isInElement() ? ElementType::node : ElementType::layer);
196 aInfo.flags = aAttributes;
197 aInfo.op = bClear ? Operation::clear : Operation::modify;
199 m_aFormatter.prepareElement(aInfo);
201 this->startNode();
203 catch (sax::SAXException & xe)
205 translateSAXException(xe,this);
208 // -----------------------------------------------------------------------------
210 void LayerWriter::prepareAddOrReplaceElement(
211 rtl::OUString const & name, sal_Int16 attributes)
213 ElementInfo info(name, ElementType::node);
214 info.flags = attributes &
215 ~com::sun::star::configuration::backend::NodeAttribute::FUSE;
216 info.op =
217 (attributes &
218 com::sun::star::configuration::backend::NodeAttribute::FUSE)
219 == 0
220 ? Operation::replace : Operation::fuse;
221 m_aFormatter.prepareElement(info);
224 void SAL_CALL LayerWriter::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
225 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
226 uno::RuntimeException)
228 checkInElement(true);
232 prepareAddOrReplaceElement(aName, aAttributes);
234 this->startNode();
236 catch (sax::SAXException & xe)
238 translateSAXException(xe,this);
241 // -----------------------------------------------------------------------------
243 void SAL_CALL LayerWriter::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
244 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
245 uno::RuntimeException)
247 checkInElement(true);
251 prepareAddOrReplaceElement(aName, aAttributes);
252 m_aFormatter.addInstanceType(aTemplate.Name,aTemplate.Component);
254 this->startNode();
256 catch (sax::SAXException & xe)
258 translateSAXException(xe,this);
261 // -----------------------------------------------------------------------------
263 void SAL_CALL LayerWriter::endNode( )
264 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
265 uno::RuntimeException)
267 checkInElement(true);
270 this->endElement();
272 catch (sax::SAXException & xe)
274 translateSAXException(xe,this);
277 // -----------------------------------------------------------------------------
279 void SAL_CALL LayerWriter::dropNode( const rtl::OUString& aName )
280 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
281 uno::RuntimeException)
283 checkInElement(true);
287 ElementInfo aInfo(aName, ElementType::node);
288 aInfo.flags = 0;
289 aInfo.op = Operation::remove;
291 m_aFormatter.prepareElement(aInfo);
293 this->startNode();
294 this->endElement();
296 catch (sax::SAXException & xe)
298 translateSAXException(xe,this);
301 // -----------------------------------------------------------------------------
303 void SAL_CALL LayerWriter::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
304 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
305 uno::RuntimeException)
307 checkInElement(true);
311 ElementInfo aInfo(aName, ElementType::property);
312 aInfo.flags = aAttributes;
313 aInfo.op = Operation::replace;
315 m_aFormatter.prepareElement(aInfo);
317 this->startProp(aType, true);
318 this->writeValue(uno::Any());
319 this->endElement();
321 catch (sax::SAXException & xe)
323 translateSAXException(xe,this);
326 // -----------------------------------------------------------------------------
328 void SAL_CALL LayerWriter::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
329 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
330 uno::RuntimeException)
332 checkInElement(true);
336 ElementInfo aInfo(aName, ElementType::property);
337 aInfo.flags = aAttributes;
338 aInfo.op = Operation::replace;
340 m_aFormatter.prepareElement(aInfo);
342 this->startProp(aValue.getValueType(), true);
343 this->writeValue(aValue);
344 this->endElement();
346 catch (sax::SAXException & xe)
348 translateSAXException(xe,this);
351 // -----------------------------------------------------------------------------
353 void SAL_CALL LayerWriter::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
354 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
355 uno::RuntimeException)
357 checkInElement(true);
361 ElementInfo aInfo(aName, ElementType::property);
362 aInfo.flags = aAttributes;
363 aInfo.op = bClear ? Operation::modify : Operation::modify;
365 m_aFormatter.prepareElement(aInfo);
367 this->startProp(aType, aType.getTypeClass() != uno::TypeClass_VOID);
369 catch (sax::SAXException & xe)
371 translateSAXException(xe,this);
374 // -----------------------------------------------------------------------------
376 void SAL_CALL LayerWriter::endProperty( )
377 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
378 uno::RuntimeException)
382 checkInElement(true,true);
383 this->endElement();
385 catch (sax::SAXException & xe)
387 translateSAXException(xe,this);
390 // -----------------------------------------------------------------------------
392 void SAL_CALL LayerWriter::setPropertyValue( const uno::Any& aValue )
393 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
394 uno::RuntimeException)
398 checkInElement(true,true);
399 this->writeValue(aValue);
401 catch (sax::SAXException & xe)
403 translateSAXException(xe,this);
406 // -----------------------------------------------------------------------------
408 void SAL_CALL LayerWriter::setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString& aLocale )
409 throw (backenduno::MalformedDataException, lang::WrappedTargetException,
410 uno::RuntimeException)
414 checkInElement(true,true);
415 this->writeValue(aValue,aLocale);
417 catch (sax::SAXException & xe)
419 translateSAXException(xe,this);
422 // -----------------------------------------------------------------------------
424 void LayerWriter::raiseMalformedDataException(sal_Char const * pMsg)
426 OSL_ASSERT(pMsg);
427 rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
429 throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
431 // -----------------------------------------------------------------------------
433 void LayerWriter::raiseIllegalTypeException(sal_Char const * pMsg)
435 OSL_ASSERT(pMsg);
436 rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
438 com::sun::star::beans::IllegalTypeException e( sMsg, *this );
439 throw backenduno::MalformedDataException( sMsg, *this, uno::makeAny(e) );
441 // -----------------------------------------------------------------------------
443 bool LayerWriter::isInElement() const
445 return !m_aTagStack.empty();
447 // -----------------------------------------------------------------------------
449 void LayerWriter::checkInElement(bool bInElement, bool bInProperty)
451 if (bInElement != this->isInElement())
453 sal_Char const * pMsg = bInElement ?
454 "LayerWriter: Illegal Data: Operation requires a started node" :
455 "LayerWriter: Illegal Data: There is a started node already" ;
456 raiseMalformedDataException(pMsg);
459 if (bInProperty != m_bInProperty)
461 sal_Char const * pMsg = bInProperty ?
462 "LayerWriter: Illegal Data: Operation requires a started property" :
463 "LayerWriter: Illegal Data: There is a started property already" ;
464 raiseMalformedDataException(pMsg);
467 // -----------------------------------------------------------------------------
469 void LayerWriter::startNode()
471 rtl::OUString sTag = m_aFormatter.getElementTag();
472 getWriteHandler()->startElement(sTag,m_aFormatter.getElementAttributes());
473 getWriteHandler()->ignorableWhitespace(rtl::OUString());
474 m_aTagStack.push(sTag);
476 // -----------------------------------------------------------------------------
478 void LayerWriter::startProp(uno::Type const & _aType, bool bNeedType)
480 if (bNeedType && _aType == uno::Type())
481 raiseIllegalTypeException("LayerWriter: Illegal Data: Cannot add VOID property");
483 m_aFormatter.addPropertyValueType(_aType);
485 startNode();
487 m_aPropertyType = _aType;
488 m_bInProperty = true;
490 // -----------------------------------------------------------------------------
492 void LayerWriter::endElement()
494 OSL_ASSERT(!m_aTagStack.empty()); // checks done elsewhere
496 getWriteHandler()->endElement(m_aTagStack.top());
497 getWriteHandler()->ignorableWhitespace(rtl::OUString());
499 m_aTagStack.pop();
500 m_bInProperty = false;
502 // -----------------------------------------------------------------------------
504 void LayerWriter::writeValue(uno::Any const & _aValue)
506 m_aFormatter.prepareSimpleElement( ElementType::value );
507 outputValue(_aValue);
509 // -----------------------------------------------------------------------------
511 void LayerWriter::writeValue(uno::Any const & _aValue, rtl::OUString const & _aLocale)
513 m_aFormatter.prepareSimpleElement( ElementType::value );
514 m_aFormatter.addLanguage(_aLocale);
515 outputValue(_aValue);
517 // -----------------------------------------------------------------------------
519 void LayerWriter::outputValue(uno::Any const & _aValue)
521 ValueFormatter aValueFormatter(_aValue);
523 aValueFormatter.addValueAttributes(m_aFormatter);
525 rtl::OUString sTag = m_aFormatter.getElementTag();
526 rtl::OUString sContent = aValueFormatter.getContent( this->m_xTCV );
528 uno::Reference< sax::XDocumentHandler > xOut = getWriteHandler();
529 xOut->startElement(sTag, m_aFormatter.getElementAttributes());
531 if (sContent.getLength()) xOut->characters(sContent);
533 xOut->endElement(sTag);
534 xOut->ignorableWhitespace(rtl::OUString());
536 // -----------------------------------------------------------------------------
538 // -----------------------------------------------------------------------------
539 // -----------------------------------------------------------------------------
540 } // namespace
542 // -----------------------------------------------------------------------------
543 } // namespace