1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "xformsapi.hxx"
23 #include <com/sun/star/frame/XModel.hpp>
24 #include <com/sun/star/uno/Reference.hxx>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/container/XNameAccess.hpp>
27 #include <com/sun/star/xforms/XFormsSupplier.hpp>
28 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
29 #include <com/sun/star/xforms/Model.hpp>
30 #include <com/sun/star/xforms/XModel2.hpp>
31 #include <com/sun/star/container/XNameContainer.hpp>
32 #include <com/sun/star/xsd/DataTypeClass.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <sal/log.hxx>
36 #include <comphelper/diagnose_ex.hxx>
38 #include <xmloff/xmltoken.hxx>
39 #include <xmloff/namespacemap.hxx>
40 #include <xmloff/xmlnamespace.hxx>
41 #include <xmloff/xmltkmap.hxx>
43 using com::sun::star::uno::Reference
;
44 using com::sun::star::uno::Sequence
;
45 using com::sun::star::uno::UNO_QUERY
;
46 using com::sun::star::uno::UNO_QUERY_THROW
;
47 using com::sun::star::beans::XPropertySet
;
48 using com::sun::star::container::XNameAccess
;
49 using com::sun::star::xforms::XFormsSupplier
;
50 using com::sun::star::xforms::XDataTypeRepository
;
51 using com::sun::star::xforms::Model
;
52 using com::sun::star::xforms::XModel2
;
53 using com::sun::star::container::XNameContainer
;
54 using com::sun::star::uno::Any
;
55 using com::sun::star::uno::Exception
;
57 using namespace com::sun::star
;
58 using namespace xmloff::token
;
60 Reference
<XModel2
> xforms_createXFormsModel()
62 Reference
<XModel2
> xModel
= Model::create( comphelper::getProcessComponentContext() );
67 void xforms_addXFormsModel(
68 const Reference
<frame::XModel
>& xDocument
,
69 const Reference
<xforms::XModel2
>& xModel
)
71 bool bSuccess
= false;
74 Reference
<XFormsSupplier
> xSupplier( xDocument
, UNO_QUERY
);
77 Reference
<XNameContainer
> xForms
= xSupplier
->getXForms();
81 xModel
->getPropertyValue("ID") >>= sName
;
82 xForms
->insertByName( sName
, Any( xModel
) );
87 catch( const Exception
& )
92 // TODO: implement proper error handling
93 SAL_WARN_IF( !bSuccess
, "xmloff", "can't import model" );
96 static Reference
<XPropertySet
> lcl_findXFormsBindingOrSubmission(
97 Reference
<frame::XModel
> const & xDocument
,
98 const OUString
& rBindingID
,
101 // find binding by iterating over all models, and look for the
104 Reference
<XPropertySet
> xRet
;
108 Reference
<XFormsSupplier
> xSupplier( xDocument
, UNO_QUERY
);
112 Reference
<XNameContainer
> xForms
= xSupplier
->getXForms();
115 // iterate over all models
116 const Sequence
<OUString
> aNames
= xForms
->getElementNames();
117 for( const auto& rName
: aNames
)
119 Reference
<xforms::XModel2
> xModel(
120 xForms
->getByName( rName
), UNO_QUERY
);
123 // ask model for bindings
124 Reference
<XNameAccess
> xBindings(
126 ? xModel
->getBindings()
127 : xModel
->getSubmissions(),
130 // finally, ask binding for name
131 if( xBindings
->hasByName( rBindingID
) )
132 xRet
.set( xBindings
->getByName( rBindingID
),
142 catch( const Exception
& )
147 // TODO: if (!xRet.is()) rImport.SetError(...);
152 Reference
<XPropertySet
> xforms_findXFormsBinding(
153 Reference
<frame::XModel
> const & xDocument
,
154 const OUString
& rBindingID
)
156 return lcl_findXFormsBindingOrSubmission( xDocument
, rBindingID
, true );
159 Reference
<XPropertySet
> xforms_findXFormsSubmission(
160 Reference
<frame::XModel
> const & xDocument
,
161 const OUString
& rBindingID
)
163 return lcl_findXFormsBindingOrSubmission( xDocument
, rBindingID
, false );
166 void xforms_setValueAny( Reference
<XPropertySet
> const & xPropertySet
,
167 const OUString
& rName
,
170 xPropertySet
->setPropertyValue( rName
, rAny
);
173 const SvXMLTokenMapEntry aTypes
[] =
175 { XML_NAMESPACE_XSD
, xmloff::token::XML_STRING
, xmloff::token::XML_STRING
},
176 { XML_NAMESPACE_XSD
, xmloff::token::XML_DECIMAL
, xmloff::token::XML_DECIMAL
},
177 { XML_NAMESPACE_XSD
, xmloff::token::XML_DOUBLE
, xmloff::token::XML_DOUBLE
},
178 { XML_NAMESPACE_XSD
, xmloff::token::XML_FLOAT
, xmloff::token::XML_FLOAT
},
179 { XML_NAMESPACE_XSD
, xmloff::token::XML_BOOLEAN
, xmloff::token::XML_BOOLEAN
},
180 { XML_NAMESPACE_XSD
, xmloff::token::XML_ANYURI
, xmloff::token::XML_ANYURI
},
181 { XML_NAMESPACE_XSD
, xmloff::token::XML_DATETIME_XSD
, xmloff::token::XML_DATETIME_XSD
},
182 { XML_NAMESPACE_XSD
, xmloff::token::XML_DATE
, xmloff::token::XML_DATE
},
183 { XML_NAMESPACE_XSD
, xmloff::token::XML_TIME
, xmloff::token::XML_TIME
},
184 { XML_NAMESPACE_XSD
, xmloff::token::XML_YEAR
, xmloff::token::XML_YEAR
},
185 { XML_NAMESPACE_XSD
, xmloff::token::XML_MONTH
, xmloff::token::XML_MONTH
},
186 { XML_NAMESPACE_XSD
, xmloff::token::XML_DAY
, xmloff::token::XML_DAY
},
190 sal_uInt16
xforms_getTypeClass(
191 const Reference
<XDataTypeRepository
>& xRepository
,
192 const SvXMLNamespaceMap
& rNamespaceMap
,
193 const OUString
& rXMLName
)
195 // translate name into token for local name
197 sal_uInt16 nPrefix
= rNamespaceMap
.GetKeyByAttrValueQName(rXMLName
, &sLocalName
);
198 static const SvXMLTokenMap
aMap( aTypes
);
199 sal_uInt16 nToken
= aMap
.Get( nPrefix
, sLocalName
);
201 sal_uInt16 nTypeClass
= css::xsd::DataTypeClass::STRING
;
202 if( nToken
!= XML_TOK_UNKNOWN
)
204 // we found an XSD name: then get the proper API name for it
205 SAL_WARN_IF( !xRepository
.is(), "xmloff", "can't find type without repository");
209 nTypeClass
= css::xsd::DataTypeClass::STRING
;
212 nTypeClass
= css::xsd::DataTypeClass::anyURI
;
215 nTypeClass
= css::xsd::DataTypeClass::DECIMAL
;
218 nTypeClass
= css::xsd::DataTypeClass::DOUBLE
;
221 nTypeClass
= css::xsd::DataTypeClass::FLOAT
;
224 nTypeClass
= css::xsd::DataTypeClass::BOOLEAN
;
226 case XML_DATETIME_XSD
:
227 nTypeClass
= css::xsd::DataTypeClass::DATETIME
;
230 nTypeClass
= css::xsd::DataTypeClass::DATE
;
233 nTypeClass
= css::xsd::DataTypeClass::TIME
;
236 nTypeClass
= css::xsd::DataTypeClass::gYear
;
239 nTypeClass
= css::xsd::DataTypeClass::gDay
;
242 nTypeClass
= css::xsd::DataTypeClass::gMonth
;
245 /* data types not yet supported:
246 nTypeClass = css::xsd::DataTypeClass::DURATION;
247 nTypeClass = css::xsd::DataTypeClass::gYearMonth;
248 nTypeClass = css::xsd::DataTypeClass::gMonthDay;
249 nTypeClass = css::xsd::DataTypeClass::hexBinary;
250 nTypeClass = css::xsd::DataTypeClass::base64Binary;
251 nTypeClass = css::xsd::DataTypeClass::QName;
252 nTypeClass = css::xsd::DataTypeClass::NOTATION;
261 OUString
xforms_getTypeName(
262 const Reference
<XDataTypeRepository
>& xRepository
,
263 const SvXMLNamespaceMap
& rNamespaceMap
,
264 const OUString
& rXMLName
)
267 sal_uInt16 nPrefix
= rNamespaceMap
.GetKeyByAttrValueQName(rXMLName
, &sLocalName
);
268 static const SvXMLTokenMap
aMap( aTypes
);
269 sal_uInt16 nToken
= aMap
.Get( nPrefix
, sLocalName
);
270 return ( nToken
== XML_TOK_UNKNOWN
)
272 : xforms_getBasicTypeName( xRepository
, rNamespaceMap
, rXMLName
);
275 OUString
xforms_getBasicTypeName(
276 const Reference
<XDataTypeRepository
>& xRepository
,
277 const SvXMLNamespaceMap
& rNamespaceMap
,
278 const OUString
& rXMLName
)
280 OUString sTypeName
= rXMLName
;
284 xRepository
->getBasicDataType(
285 xforms_getTypeClass( xRepository
, rNamespaceMap
, rXMLName
) )
288 catch( const Exception
& )
290 TOOLS_WARN_EXCEPTION("xmloff", "exception during type creation");
295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */