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 #include "TokenContext.hxx" 31 #include <xmloff/xmltkmap.hxx> 32 #include <xmloff/xmlimp.hxx> 33 #include <xmloff/nmspmap.hxx> 34 #include "xmloff/xmlerror.hxx" 35 36 #include <tools/debug.hxx> 37 38 using rtl::OUString; 39 using com::sun::star::uno::Reference; 40 using com::sun::star::xml::sax::XAttributeList; 41 42 43 struct SvXMLTokenMapEntry aEmptyMap[1] = 44 { 45 XML_TOKEN_MAP_END 46 }; 47 48 49 TokenContext::TokenContext( SvXMLImport& rImport, 50 sal_uInt16 nPrefix, 51 const OUString& rLocalName, 52 const SvXMLTokenMapEntry* pAttributes, 53 const SvXMLTokenMapEntry* pChildren ) 54 : SvXMLImportContext( rImport, nPrefix, rLocalName ), 55 mpAttributes( pAttributes ), 56 mpChildren( pChildren ) 57 { 58 } 59 60 TokenContext::~TokenContext() 61 { 62 } 63 64 void TokenContext::StartElement( 65 const Reference<XAttributeList>& xAttributeList ) 66 { 67 // iterate over attributes 68 // - if in map: call HandleAttribute 69 // - xmlns:... : ignore 70 // - other: warning 71 DBG_ASSERT( mpAttributes != NULL, "no token map for attributes" ); 72 SvXMLTokenMap aMap( mpAttributes ); 73 74 sal_Int16 nCount = xAttributeList->getLength(); 75 for( sal_Int16 i = 0; i < nCount; i++ ) 76 { 77 // get key/local-name pair from namespace map 78 OUString sLocalName; 79 sal_uInt16 nPrefix = GetImport().GetNamespaceMap(). 80 GetKeyByAttrName( xAttributeList->getNameByIndex(i), &sLocalName ); 81 82 // get token from token map 83 sal_uInt16 nToken = aMap.Get( nPrefix, sLocalName ); 84 85 // and the value... 86 const OUString& rValue = xAttributeList->getValueByIndex(i); 87 88 if( nToken != XML_TOK_UNKNOWN ) 89 { 90 HandleAttribute( nToken, rValue ); 91 } 92 else if( nPrefix != XML_NAMESPACE_XMLNS ) 93 { 94 // error handling, for all attribute that are not 95 // namespace declarations 96 GetImport().SetError( XMLERROR_UNKNOWN_ATTRIBUTE, 97 sLocalName, rValue); 98 } 99 } 100 } 101 102 SvXMLImportContext* TokenContext::CreateChildContext( 103 sal_uInt16 nPrefix, 104 const OUString& rLocalName, 105 const Reference<XAttributeList>& xAttrList ) 106 { 107 // call HandleChild for elements in token map. Ignore other content. 108 109 SvXMLImportContext* pContext = NULL; 110 111 DBG_ASSERT( mpChildren != NULL, "no token map for child elements" ); 112 SvXMLTokenMap aMap( mpChildren ); 113 sal_uInt16 nToken = aMap.Get( nPrefix, rLocalName ); 114 if( nToken != XML_TOK_UNKNOWN ) 115 { 116 // call handle child, and pass down arguments 117 pContext = HandleChild( nToken, nPrefix, rLocalName, xAttrList ); 118 } 119 120 // error handling: create default context and generate warning 121 if( pContext == NULL ) 122 { 123 GetImport().SetError( XMLERROR_UNKNOWN_ELEMENT, rLocalName ); 124 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); 125 } 126 return pContext; 127 } 128 129 bool lcl_IsWhiteSpace( sal_Unicode c ) 130 { 131 return c == sal_Unicode( ' ' ) 132 || c == sal_Unicode( 0x09 ) 133 || c == sal_Unicode( 0x0A ) 134 || c == sal_Unicode( 0x0D ); 135 } 136 137 void TokenContext::Characters( const ::rtl::OUString& rCharacters ) 138 { 139 // get iterators for string data 140 const sal_Unicode* pBegin = rCharacters.getStr(); 141 const sal_Unicode* pEnd = &( pBegin[ rCharacters.getLength() ] ); 142 143 // raise error if non-whitespace character is found 144 if( ::std::find_if( pBegin, pEnd, ::std::not1(::std::ptr_fun(lcl_IsWhiteSpace)) ) != pEnd ) 145 GetImport().SetError( XMLERROR_UNKNOWN_CHARACTERS, rCharacters ); 146 } 147