1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: layerwriter.cxx,v $
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"
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 // -----------------------------------------------------------------------------
48 // -----------------------------------------------------------------------------
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 // -----------------------------------------------------------------------------
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 // -----------------------------------------------------------------------------
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
);
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
);
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
);
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();
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
);
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
;
218 com::sun::star::configuration::backend::NodeAttribute::FUSE
)
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
);
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
);
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);
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
);
289 aInfo
.op
= Operation::remove
;
291 m_aFormatter
.prepareElement(aInfo
);
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());
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
);
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);
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
)
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
)
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
);
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());
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 // -----------------------------------------------------------------------------
542 // -----------------------------------------------------------------------------