1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26
27 #include "XFormsBindContext.hxx"
28
29 #include "xformsapi.hxx"
30
31 #include <xmloff/xmlimp.hxx>
32 #include "xmloff/xmlerror.hxx"
33 #include <xmloff/xmltoken.hxx>
34 #include <xmloff/xmltkmap.hxx>
35 #include "xmloff/xmlnmspe.hxx"
36 #include <xmloff/nmspmap.hxx>
37
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/xforms/XModel.hpp>
40
41 #include <tools/debug.hxx>
42
43 using rtl::OUString;
44 using com::sun::star::beans::XPropertySet;
45 using com::sun::star::uno::Reference;
46 using com::sun::star::uno::makeAny;
47 using com::sun::star::uno::UNO_QUERY;
48 using com::sun::star::uno::UNO_QUERY_THROW;
49 using com::sun::star::container::XNameContainer;
50 using com::sun::star::xml::sax::XAttributeList;
51 using com::sun::star::xforms::XModel;
52 using namespace xmloff::token;
53
54
55
56
57 static struct SvXMLTokenMapEntry aAttributeMap[] =
58 {
59 TOKEN_MAP_ENTRY( NONE, NODESET ),
60 TOKEN_MAP_ENTRY( NONE, ID ),
61 TOKEN_MAP_ENTRY( NONE, READONLY ),
62 TOKEN_MAP_ENTRY( NONE, RELEVANT ),
63 TOKEN_MAP_ENTRY( NONE, REQUIRED ),
64 TOKEN_MAP_ENTRY( NONE, CONSTRAINT ),
65 TOKEN_MAP_ENTRY( NONE, CALCULATE ),
66 TOKEN_MAP_ENTRY( NONE, TYPE ),
67 XML_TOKEN_MAP_END
68 };
69
70 // helper function; see below
71 void lcl_fillNamespaceContainer( const SvXMLNamespaceMap&,
72 Reference<XNameContainer>& );
73
XFormsBindContext(SvXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLocalName,const Reference<XPropertySet> & xModel)74 XFormsBindContext::XFormsBindContext(
75 SvXMLImport& rImport,
76 sal_uInt16 nPrefix,
77 const OUString& rLocalName,
78 const Reference<XPropertySet>& xModel ) :
79 TokenContext( rImport, nPrefix, rLocalName, aAttributeMap, aEmptyMap ),
80 mxModel( xModel, UNO_QUERY_THROW ),
81 mxBinding( NULL )
82 {
83 // attach binding to model
84 mxBinding = mxModel->createBinding();
85 DBG_ASSERT( mxBinding.is(), "can't create binding" );
86 mxModel->getBindings()->insert( makeAny( mxBinding ) );
87 }
88
~XFormsBindContext()89 XFormsBindContext::~XFormsBindContext()
90 {
91 }
92
HandleAttribute(sal_uInt16 nToken,const OUString & rValue)93 void XFormsBindContext::HandleAttribute( sal_uInt16 nToken,
94 const OUString& rValue )
95 {
96 switch( nToken )
97 {
98 case XML_NODESET:
99 lcl_setValue( mxBinding, OUSTRING("BindingExpression"), rValue );
100 break;
101 case XML_ID:
102 lcl_setValue( mxBinding, OUSTRING("BindingID"), rValue );
103 break;
104 case XML_READONLY:
105 lcl_setValue( mxBinding, OUSTRING("ReadonlyExpression"), rValue );
106 break;
107 case XML_RELEVANT:
108 lcl_setValue( mxBinding, OUSTRING("RelevantExpression"), rValue );
109 break;
110 case XML_REQUIRED:
111 lcl_setValue( mxBinding, OUSTRING("RequiredExpression"), rValue );
112 break;
113 case XML_CONSTRAINT:
114 lcl_setValue( mxBinding, OUSTRING("ConstraintExpression"), rValue );
115 break;
116 case XML_CALCULATE:
117 lcl_setValue( mxBinding, OUSTRING("CalculateExpression"), rValue );
118 break;
119 case XML_TYPE:
120 lcl_setValue( mxBinding, OUSTRING("Type"),
121 makeAny( lcl_getTypeName( mxModel->getDataTypeRepository(),
122 GetImport().GetNamespaceMap(),
123 rValue ) ) );
124 break;
125 default:
126 DBG_ERROR( "should not happen" );
127 break;
128 }
129 }
130
StartElement(const Reference<XAttributeList> & xAttributeList)131 void XFormsBindContext::StartElement(
132 const Reference<XAttributeList>& xAttributeList )
133 {
134 // we need to register the namespaces
135 Reference<XNameContainer> xContainer(
136 mxBinding->getPropertyValue( OUSTRING("BindingNamespaces") ),
137 UNO_QUERY );
138
139 DBG_ASSERT( xContainer.is(), "binding should have a namespace container" );
140 if( xContainer.is() )
141 lcl_fillNamespaceContainer( GetImport().GetNamespaceMap(), xContainer);
142
143 // call super-class for attribute handling
144 TokenContext::StartElement( xAttributeList );
145 }
146
147 /** will be called for each child element */
HandleChild(sal_uInt16,sal_uInt16,const OUString &,const Reference<XAttributeList> &)148 SvXMLImportContext* XFormsBindContext::HandleChild(
149 sal_uInt16,
150 sal_uInt16,
151 const OUString&,
152 const Reference<XAttributeList>& )
153 {
154 DBG_ERROR( "no children supported" );
155 return NULL;
156 }
157
158
lcl_fillNamespaceContainer(const SvXMLNamespaceMap & aMap,Reference<XNameContainer> & xContainer)159 void lcl_fillNamespaceContainer(
160 const SvXMLNamespaceMap& aMap,
161 Reference<XNameContainer>& xContainer )
162 {
163 sal_uInt16 nKeyIter = aMap.GetFirstKey();
164 do
165 {
166 // get prefix and namespace
167 const OUString& sPrefix = aMap.GetPrefixByKey( nKeyIter );
168 const OUString& sNamespace = aMap.GetNameByKey( nKeyIter );
169
170 // as a hack, we will ignore our own 'default' namespaces
171 DBG_ASSERT( sPrefix.getLength() > 0, "no prefix?" );
172 if( sPrefix.getStr()[0] != sal_Unicode( '_' ) &&
173 nKeyIter >= XML_OLD_NAMESPACE_META_IDX )
174 {
175 // insert prefix (use replace if already known)
176 if( xContainer->hasByName( sPrefix ) )
177 xContainer->replaceByName( sPrefix, makeAny( sNamespace ) );
178 else
179 xContainer->insertByName( sPrefix, makeAny( sNamespace ) );
180 }
181
182 // proceed to next
183 nKeyIter = aMap.GetNextKey( nKeyIter );
184 }
185 while( nKeyIter != XML_NAMESPACE_UNKNOWN );
186 }
187