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: schemaparser.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 "schemaparser.hxx"
36 // -----------------------------------------------------------------------------
37 #include "wrapexception.hxx"
39 #define WRAP_PARSE_EXCEPTIONS() \
40 PASS_EXCEPTION(sax::SAXException) \
41 PASS_EXCEPTION(uno::RuntimeException) \
42 WRAP_CONFIGDATA_EXCEPTIONS( raiseParseException ) \
43 WRAP_OTHER_EXCEPTIONS( raiseParseException )
45 #define WRAP_PARSE_EXCEPTIONS_MSG( msg ) \
46 PASS_EXCEPTION(sax::SAXException) \
47 PASS_EXCEPTION(uno::RuntimeException) \
48 WRAP_CONFIGDATA_EXCEPTIONS1( raiseParseException, msg ) \
49 WRAP_OTHER_EXCEPTIONS1( raiseParseException, msg )
51 // -----------------------------------------------------------------------------
55 // -----------------------------------------------------------------------------
58 // -----------------------------------------------------------------------------
59 namespace uno
= ::com::sun::star::uno
;
60 namespace sax
= ::com::sun::star::xml::sax
;
61 // -----------------------------------------------------------------------------
63 SchemaParser::SchemaParser(uno::Reference
< uno::XComponentContext
> const & _xContext
, uno::Reference
< backenduno::XSchemaHandler
> const & _xHandler
, Select _selector
)
64 : BasicParser(_xContext
)
65 , m_xHandler(_xHandler
)
67 , m_selector(_selector
)
68 , m_selected(selectNone
)
72 rtl::OUString
sMessage(RTL_CONSTASCII_USTRINGPARAM("Cannot create SchemaParser: Unexpected NULL Handler"));
73 throw uno::RuntimeException(sMessage
, *this);
75 OSL_ENSURE(m_selector
!= selectNone
, "Warning: Schema handler will handle no part of the schema");
77 // -----------------------------------------------------------------------------
79 SchemaParser::~SchemaParser()
82 // -----------------------------------------------------------------------------
84 void SAL_CALL
SchemaParser::startDocument( )
85 throw (sax::SAXException
, uno::RuntimeException
)
87 BasicParser::startDocument();
89 OSL_ENSURE(isEmptyNode(), "BasicParser does not mark new document as empty");
91 m_sComponent
= rtl::OUString();
92 m_selected
= selectNone
;
94 // -----------------------------------------------------------------------------
96 void SAL_CALL
SchemaParser::endDocument( ) throw (sax::SAXException
, uno::RuntimeException
)
99 raiseParseException("Schema XML Parser: Invalid XML: Document ends while section is open");
101 if (isEmptyNode()) OSL_TRACE("Configuration Parser: XML schema document ended without any data");
103 BasicParser::endDocument();
105 // -----------------------------------------------------------------------------
107 void SAL_CALL
SchemaParser::startElement( const rtl::OUString
& aName
, const uno::Reference
< sax::XAttributeList
>& xAttribs
)
108 throw (sax::SAXException
, uno::RuntimeException
)
110 if ( this->isSkipping() )
112 this->startSkipping( aName
, xAttribs
);
116 ElementInfo aInfo
= getDataParser().parseElementInfo(aName
,xAttribs
);
122 case ElementType::schema
:
123 this->startSchema(aInfo
,xAttribs
);
126 case ElementType::component
:
127 this->startSection(selectComponent
, aInfo
, xAttribs
);
130 case ElementType::templates
:
131 this->startSection(selectTemplates
, aInfo
, xAttribs
);
134 case ElementType::import
:
135 this->handleImport(aInfo
,xAttribs
);
136 this->startSkipping( aName
, xAttribs
);
139 case ElementType::uses
:
140 this->startSkipping( aName
, xAttribs
);
143 case ElementType::instance
:
144 this->handleInstance(aInfo
,xAttribs
);
145 this->startSkipping( aName
, xAttribs
);
148 case ElementType::item_type
:
149 this->handleItemType(aInfo
,xAttribs
);
150 this->startSkipping( aName
, xAttribs
);
153 case ElementType::layer
:
154 case ElementType::node
:
155 raiseParseException( "Schema XML parser - Invalid data: found unspecified 'node' element.\n");
157 case ElementType::group
: case ElementType::set
:
158 this->startNode(aInfo
,xAttribs
);
159 OSL_ASSERT( this->isInNode() );
162 case ElementType::property
:
163 this->startProperty(aInfo
,xAttribs
);
164 OSL_ASSERT( this->isInUnhandledProperty() );
167 case ElementType::value
:
168 this->startValueData(xAttribs
);
169 OSL_ASSERT( this->isInValueData() );
172 default: // skip unknown elements
173 OSL_ENSURE( aInfo
.type
<= ElementType::other
, "Schema XML parser - Error: invalid element type value\n");
174 OSL_ENSURE( aInfo
.type
>= ElementType::other
, "Schema XML parser - Unexpected: found layer element in schema data\n");
175 // accept (and skip) unknown (ElementType::other) tags in schema to allow documentation and constraints to pass without assertion
176 //OSL_ENSURE( aInfo.type < ElementType::other, "Schema XML parser - Warning: ignoring unknown element tag\n");
178 this->startSkipping( aName
, xAttribs
);
179 OSL_ASSERT( this->isSkipping() );
183 WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Starting Element")
185 OSL_ENSURE(aInfo
.op
== Operation::none
|| this->isSkipping(),
186 "Schema Parser: The 'op' attribute is not supported in a schema");
188 // -----------------------------------------------------------------------------
190 void SAL_CALL
SchemaParser::endElement( const rtl::OUString
& aName
)
191 throw (sax::SAXException
, uno::RuntimeException
)
193 if ( this->wasSkipping(aName
) )
198 if ( this->isInValueData())
199 this->endValueData();
201 else if (this->isInProperty())
204 else if (this->isInNode())
207 else if (this->isSelected())
213 WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Ending Element")
215 // -----------------------------------------------------------------------------
216 // -----------------------------------------------------------------------------
218 void SchemaParser::startSchema( ElementInfo
const & aInfo
, const uno::Reference
< sax::XAttributeList
>& /*xAttribs*/ )
220 m_sComponent
= aInfo
.name
;
221 m_xHandler
->startSchema();
223 // -----------------------------------------------------------------------------
225 void SchemaParser::endSchema( )
227 m_xHandler
->endSchema();
228 m_sComponent
= rtl::OUString();
230 // -----------------------------------------------------------------------------
232 bool SchemaParser::select(Select _select
)
235 raiseParseException("Schema XML parser - Invalid data: found start of section while a section is still open.\n");
237 m_selected
= static_cast<Select
>(m_selector
& _select
);
239 return m_selected
!= 0;
241 // -----------------------------------------------------------------------------
243 void SchemaParser::startSection( Select _select
, ElementInfo
const & aInfo
, const uno::Reference
< sax::XAttributeList
>& xAttribs
)
245 if (this->select(_select
))
247 if (_select
== selectComponent
)
249 m_xHandler
->startComponent(m_sComponent
);
253 startSkipping(aInfo
.name
,xAttribs
);
255 // -----------------------------------------------------------------------------
257 void SchemaParser::endSection( )
259 if (m_selected
== selectComponent
)
261 m_xHandler
->endComponent();
263 m_selected
= selectNone
;
265 // -----------------------------------------------------------------------------
267 void SchemaParser::handleImport( ElementInfo
const & /*aInfo*/, const uno::Reference
< sax::XAttributeList
>& xAttribs
)
269 rtl::OUString aComponent
;
270 if (getDataParser().getImportComponent(xAttribs
,aComponent
))
271 m_xHandler
->importComponent(aComponent
);
274 raiseParseException("Schema XML parser - Invalid data: Missing component attribute for import directive.\n");
276 // -----------------------------------------------------------------------------
278 void SchemaParser::handleInstance( ElementInfo
const & aInfo
, const uno::Reference
< sax::XAttributeList
>& xAttribs
)
280 backenduno::TemplateIdentifier aTemplate
;
281 if (getDataParser().getInstanceType(xAttribs
, aTemplate
.Name
, aTemplate
.Component
))
282 m_xHandler
->addInstance(aInfo
.name
, aTemplate
);
285 raiseParseException("Schema XML parser - Invalid data: Missing type information for instantiation directive.\n");
287 // -----------------------------------------------------------------------------
289 void SchemaParser::handleItemType( ElementInfo
const & /*aInfo*/, const uno::Reference
< sax::XAttributeList
>& xAttribs
)
291 backenduno::TemplateIdentifier aTemplate
;
292 if (getDataParser().getInstanceType(xAttribs
, aTemplate
.Name
, aTemplate
.Component
))
293 m_xHandler
->addItemType(aTemplate
);
296 raiseParseException("Schema XML parser - Invalid data: Missing type information for instantiation directive.\n");
298 // -----------------------------------------------------------------------------
300 void SchemaParser::startNode( ElementInfo
const & aInfo
, const uno::Reference
< sax::XAttributeList
>& xAttribs
)
302 bool bStartTemplate
= ( !isInNode() && m_selected
== selectTemplates
);
304 BasicParser::startNode(aInfo
,xAttribs
);
306 OSL_ASSERT(aInfo
.type
== ElementType::set
|| aInfo
.type
== ElementType::group
);
308 if (aInfo
.type
== ElementType::group
)
311 m_xHandler
->startGroupTemplate( backenduno::TemplateIdentifier(aInfo
.name
,m_sComponent
), aInfo
.flags
);
314 m_xHandler
->startGroup( aInfo
.name
, aInfo
.flags
);
318 backenduno::TemplateIdentifier aItemType
;
320 if (!getDataParser().getSetElementType(xAttribs
, aItemType
.Name
, aItemType
.Component
))
321 raiseParseException("Schema XML parser - Invalid data: Missing item-type information for set node.\n");
324 m_xHandler
->startSetTemplate( backenduno::TemplateIdentifier(aInfo
.name
,m_sComponent
), aInfo
.flags
, aItemType
);
327 m_xHandler
->startSet( aInfo
.name
, aInfo
.flags
, aItemType
);
330 // -----------------------------------------------------------------------------
332 void SchemaParser::endNode()
334 BasicParser::endNode();
336 bool bEndedTemplate
= ( !isInNode() && m_selected
== selectTemplates
);
339 m_xHandler
->endTemplate();
342 m_xHandler
->endNode();
344 // -----------------------------------------------------------------------------
346 void SchemaParser::startProperty( ElementInfo
const & aInfo
, const uno::Reference
< sax::XAttributeList
>& xAttribs
)
348 BasicParser::startProperty(aInfo
,xAttribs
);
350 OSL_ENSURE( isInUnhandledProperty(), "Property not recognizable as unhandled");
352 // -----------------------------------------------------------------------------
354 void SchemaParser::endProperty()
356 if (isInUnhandledProperty())
358 ElementInfo
const & aInfo
= this->getActiveNodeInfo();
360 m_xHandler
->addProperty(aInfo
.name
,
362 getActivePropertyType());
365 BasicParser::endProperty();
367 // -----------------------------------------------------------------------------
369 void SchemaParser::startValueData(const uno::Reference
< sax::XAttributeList
>& xAttribs
)
371 OSL_ENSURE( this->isInUnhandledProperty(),"Schema XML parser - multiple values in property are not permitted in the schema.\n");
373 BasicParser::startValueData(xAttribs
);
375 if (this->isValueDataLocalized())
376 getLogger().warning("Language attributes on values are ignored in the schema.",
377 "endValueData()","configuration::xml::SchemaParser");
379 // -----------------------------------------------------------------------------
381 void SchemaParser::endValueData()
383 uno::Any aValue
= this->getCurrentValue();
385 ElementInfo
const & aInfo
= this->getActiveNodeInfo();
387 if (aValue
.hasValue())
389 m_xHandler
->addPropertyWithDefault(aInfo
.name
,aInfo
.flags
,aValue
);
393 getLogger().warning("Found deprecated explicit NIL value in schema data.",
394 "endValueData()","configuration::xml::SchemaParser");
395 m_xHandler
->addProperty(aInfo
.name
,aInfo
.flags
,getActivePropertyType());
398 BasicParser::endValueData();
400 OSL_ENSURE( !isInUnhandledProperty(), "Property not recognizable as handled");
402 // -----------------------------------------------------------------------------
404 // -----------------------------------------------------------------------------
407 // -----------------------------------------------------------------------------