1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmloff.hxx" 30 31 #include "XFormsBindContext.hxx" 32 33 #include "xformsapi.hxx" 34 35 #include <xmloff/xmlimp.hxx> 36 #include "xmloff/xmlerror.hxx" 37 #include <xmloff/xmltoken.hxx> 38 #include <xmloff/xmltkmap.hxx> 39 #include "xmloff/xmlnmspe.hxx" 40 #include <xmloff/nmspmap.hxx> 41 42 #include <com/sun/star/container/XNameContainer.hpp> 43 #include <com/sun/star/xforms/XModel.hpp> 44 45 #include <tools/debug.hxx> 46 47 using rtl::OUString; 48 using com::sun::star::beans::XPropertySet; 49 using com::sun::star::uno::Reference; 50 using com::sun::star::uno::makeAny; 51 using com::sun::star::uno::UNO_QUERY; 52 using com::sun::star::uno::UNO_QUERY_THROW; 53 using com::sun::star::container::XNameContainer; 54 using com::sun::star::xml::sax::XAttributeList; 55 using com::sun::star::xforms::XModel; 56 using namespace xmloff::token; 57 58 59 60 61 static struct SvXMLTokenMapEntry aAttributeMap[] = 62 { 63 TOKEN_MAP_ENTRY( NONE, NODESET ), 64 TOKEN_MAP_ENTRY( NONE, ID ), 65 TOKEN_MAP_ENTRY( NONE, READONLY ), 66 TOKEN_MAP_ENTRY( NONE, RELEVANT ), 67 TOKEN_MAP_ENTRY( NONE, REQUIRED ), 68 TOKEN_MAP_ENTRY( NONE, CONSTRAINT ), 69 TOKEN_MAP_ENTRY( NONE, CALCULATE ), 70 TOKEN_MAP_ENTRY( NONE, TYPE ), 71 XML_TOKEN_MAP_END 72 }; 73 74 // helper function; see below 75 void lcl_fillNamespaceContainer( const SvXMLNamespaceMap&, 76 Reference<XNameContainer>& ); 77 78 XFormsBindContext::XFormsBindContext( 79 SvXMLImport& rImport, 80 sal_uInt16 nPrefix, 81 const OUString& rLocalName, 82 const Reference<XPropertySet>& xModel ) : 83 TokenContext( rImport, nPrefix, rLocalName, aAttributeMap, aEmptyMap ), 84 mxModel( xModel, UNO_QUERY_THROW ), 85 mxBinding( NULL ) 86 { 87 // attach binding to model 88 mxBinding = mxModel->createBinding(); 89 DBG_ASSERT( mxBinding.is(), "can't create binding" ); 90 mxModel->getBindings()->insert( makeAny( mxBinding ) ); 91 } 92 93 XFormsBindContext::~XFormsBindContext() 94 { 95 } 96 97 void XFormsBindContext::HandleAttribute( sal_uInt16 nToken, 98 const OUString& rValue ) 99 { 100 switch( nToken ) 101 { 102 case XML_NODESET: 103 lcl_setValue( mxBinding, OUSTRING("BindingExpression"), rValue ); 104 break; 105 case XML_ID: 106 lcl_setValue( mxBinding, OUSTRING("BindingID"), rValue ); 107 break; 108 case XML_READONLY: 109 lcl_setValue( mxBinding, OUSTRING("ReadonlyExpression"), rValue ); 110 break; 111 case XML_RELEVANT: 112 lcl_setValue( mxBinding, OUSTRING("RelevantExpression"), rValue ); 113 break; 114 case XML_REQUIRED: 115 lcl_setValue( mxBinding, OUSTRING("RequiredExpression"), rValue ); 116 break; 117 case XML_CONSTRAINT: 118 lcl_setValue( mxBinding, OUSTRING("ConstraintExpression"), rValue ); 119 break; 120 case XML_CALCULATE: 121 lcl_setValue( mxBinding, OUSTRING("CalculateExpression"), rValue ); 122 break; 123 case XML_TYPE: 124 lcl_setValue( mxBinding, OUSTRING("Type"), 125 makeAny( lcl_getTypeName( mxModel->getDataTypeRepository(), 126 GetImport().GetNamespaceMap(), 127 rValue ) ) ); 128 break; 129 default: 130 DBG_ERROR( "should not happen" ); 131 break; 132 } 133 } 134 135 void XFormsBindContext::StartElement( 136 const Reference<XAttributeList>& xAttributeList ) 137 { 138 // we need to register the namespaces 139 Reference<XNameContainer> xContainer( 140 mxBinding->getPropertyValue( OUSTRING("BindingNamespaces") ), 141 UNO_QUERY ); 142 143 DBG_ASSERT( xContainer.is(), "binding should have a namespace container" ); 144 if( xContainer.is() ) 145 lcl_fillNamespaceContainer( GetImport().GetNamespaceMap(), xContainer); 146 147 // call super-class for attribute handling 148 TokenContext::StartElement( xAttributeList ); 149 } 150 151 /** will be called for each child element */ 152 SvXMLImportContext* XFormsBindContext::HandleChild( 153 sal_uInt16, 154 sal_uInt16, 155 const OUString&, 156 const Reference<XAttributeList>& ) 157 { 158 DBG_ERROR( "no children supported" ); 159 return NULL; 160 } 161 162 163 void lcl_fillNamespaceContainer( 164 const SvXMLNamespaceMap& aMap, 165 Reference<XNameContainer>& xContainer ) 166 { 167 sal_uInt16 nKeyIter = aMap.GetFirstKey(); 168 do 169 { 170 // get prefix and namespace 171 const OUString& sPrefix = aMap.GetPrefixByKey( nKeyIter ); 172 const OUString& sNamespace = aMap.GetNameByKey( nKeyIter ); 173 174 // as a hack, we will ignore our own 'default' namespaces 175 DBG_ASSERT( sPrefix.getLength() > 0, "no prefix?" ); 176 if( sPrefix.getStr()[0] != sal_Unicode( '_' ) && 177 nKeyIter >= XML_OLD_NAMESPACE_META_IDX ) 178 { 179 // insert prefix (use replace if already known) 180 if( xContainer->hasByName( sPrefix ) ) 181 xContainer->replaceByName( sPrefix, makeAny( sNamespace ) ); 182 else 183 xContainer->insertByName( sPrefix, makeAny( sNamespace ) ); 184 } 185 186 // proceed to next 187 nKeyIter = aMap.GetNextKey( nKeyIter ); 188 } 189 while( nKeyIter != XML_NAMESPACE_UNKNOWN ); 190 } 191