1a3872823SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3a3872823SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4a3872823SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5a3872823SAndrew Rist  * distributed with this work for additional information
6a3872823SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7a3872823SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8a3872823SAndrew Rist  * "License"); you may not use this file except in compliance
9a3872823SAndrew Rist  * with the License.  You may obtain a copy of the License at
10a3872823SAndrew Rist  *
11a3872823SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12a3872823SAndrew Rist  *
13a3872823SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14a3872823SAndrew Rist  * software distributed under the License is distributed on an
15a3872823SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16a3872823SAndrew Rist  * KIND, either express or implied.  See the License for the
17a3872823SAndrew Rist  * specific language governing permissions and limitations
18a3872823SAndrew Rist  * under the License.
19a3872823SAndrew Rist  *
20a3872823SAndrew Rist  *************************************************************/
21a3872823SAndrew Rist 
22a3872823SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER( update_precomp.py ): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_package.hxx"
26cdf0e10cSrcweir #include <ManifestImport.hxx>
27cdf0e10cSrcweir #include <ManifestDefines.hxx>
28cdf0e10cSrcweir #include <Base64Codec.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <com/sun/star/xml/sax/XAttributeList.hpp>
31cdf0e10cSrcweir #include <com/sun/star/xml/crypto/DigestID.hpp>
32cdf0e10cSrcweir #include <com/sun/star/xml/crypto/CipherID.hpp>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir using namespace com::sun::star::uno;
35cdf0e10cSrcweir using namespace com::sun::star::beans;
36cdf0e10cSrcweir using namespace com::sun::star;
37cdf0e10cSrcweir using namespace rtl;
38cdf0e10cSrcweir using namespace std;
39cdf0e10cSrcweir 
4076bf0a21SHerbert Dürr // helper for ignoring multiple settings of the same property
4176bf0a21SHerbert Dürr #define setProperty(e,v) do{ if(!maValues[e].hasValue()) maValues[e] <<= v;} while(0)
4276bf0a21SHerbert Dürr 
4376bf0a21SHerbert Dürr static const char* getMnfstPropName( int nManifestPropId )
4476bf0a21SHerbert Dürr {
4576bf0a21SHerbert Dürr 	const char* pName;
4676bf0a21SHerbert Dürr 	switch( nManifestPropId )
4776bf0a21SHerbert Dürr 	{
4876bf0a21SHerbert Dürr 		case PKG_MNFST_MEDIATYPE:	pName = "MediaType"; break;
4976bf0a21SHerbert Dürr 		case PKG_MNFST_VERSION:		pName = "Version"; break;
5076bf0a21SHerbert Dürr 		case PKG_MNFST_FULLPATH:	pName = "FullPath"; break;
5176bf0a21SHerbert Dürr 		case PKG_MNFST_INIVECTOR:	pName = "InitialisationVector"; break;
5276bf0a21SHerbert Dürr 		case PKG_MNFST_SALT:		pName = "Salt"; break;
5376bf0a21SHerbert Dürr 		case PKG_MNFST_ITERATION:	pName = "IterationCount"; break;
5476bf0a21SHerbert Dürr 		case PKG_MNFST_UCOMPSIZE:	pName = "Size"; break;
5576bf0a21SHerbert Dürr 		case PKG_MNFST_DIGEST:		pName = "Digest"; break;
5676bf0a21SHerbert Dürr 		case PKG_MNFST_ENCALG:		pName = "EncryptionAlgorithm"; break;
5776bf0a21SHerbert Dürr 		case PKG_MNFST_STARTALG:	pName = "StartKeyAlgorithm"; break;
5876bf0a21SHerbert Dürr 		case PKG_MNFST_DIGESTALG:	pName = "DigestAlgorithm"; break;
5976bf0a21SHerbert Dürr 		case PKG_MNFST_DERKEYSIZE:	pName = "DerivedKeySize"; break;
6076bf0a21SHerbert Dürr 		default: pName = NULL;
6176bf0a21SHerbert Dürr 	}
6276bf0a21SHerbert Dürr 	return pName;
6376bf0a21SHerbert Dürr }
6476bf0a21SHerbert Dürr 
65cdf0e10cSrcweir // ---------------------------------------------------
66cdf0e10cSrcweir ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector )
6776bf0a21SHerbert Dürr : rManVector ( rNewManVector )
68cdf0e10cSrcweir , nDerivedKeySize( 0 )
6976bf0a21SHerbert Dürr , bIgnoreEncryptData( false )
70cdf0e10cSrcweir 
71cdf0e10cSrcweir , sCdataAttribute     			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA ) )
72cdf0e10cSrcweir , sMediaTypeAttribute 			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_MEDIA_TYPE ) )
73cdf0e10cSrcweir , sVersionAttribute 			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_VERSION ) )
74cdf0e10cSrcweir , sFullPathAttribute  			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_FULL_PATH ) )
75cdf0e10cSrcweir , sSizeAttribute 				( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SIZE ) )
76cdf0e10cSrcweir , sSaltAttribute 				( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SALT ) )
7776bf0a21SHerbert Dürr , sInitialisationVectorAttribute(RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_INITIALISATION_VECTOR ) )
78cdf0e10cSrcweir , sIterationCountAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT ) )
7976bf0a21SHerbert Dürr , sKeySizeAttribute            ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_SIZE ) )
80cdf0e10cSrcweir , sAlgorithmNameAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME ) )
8176bf0a21SHerbert Dürr , sStartKeyAlgNameAttribute    ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_START_KEY_GENERATION_NAME ) )
82cdf0e10cSrcweir , sKeyDerivationNameAttribute 	( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME ) )
83cdf0e10cSrcweir , sChecksumAttribute 			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM ) )
84cdf0e10cSrcweir , sChecksumTypeAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE ) )
85cdf0e10cSrcweir {
86cdf0e10cSrcweir     aStack.reserve( 10 );
87cdf0e10cSrcweir }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir // ---------------------------------------------------
90cdf0e10cSrcweir ManifestImport::~ManifestImport ( void )
91cdf0e10cSrcweir {
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir // ---------------------------------------------------
95cdf0e10cSrcweir void SAL_CALL ManifestImport::startDocument(  )
96cdf0e10cSrcweir 		throw( xml::sax::SAXException, uno::RuntimeException )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir }
99cdf0e10cSrcweir 
100cdf0e10cSrcweir // ---------------------------------------------------
101cdf0e10cSrcweir void SAL_CALL ManifestImport::endDocument(  )
102cdf0e10cSrcweir 		throw( xml::sax::SAXException, uno::RuntimeException )
103cdf0e10cSrcweir {
104cdf0e10cSrcweir }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir // ---------------------------------------------------
107cdf0e10cSrcweir void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
108cdf0e10cSrcweir 		throw( xml::sax::SAXException, uno::RuntimeException )
109cdf0e10cSrcweir {
110cdf0e10cSrcweir     StringHashMap aConvertedAttribs;
111cdf0e10cSrcweir     ::rtl::OUString aConvertedName = PushNameAndNamespaces( aName, xAttribs, aConvertedAttribs );
112cdf0e10cSrcweir 
11376bf0a21SHerbert Dürr 	if ( aConvertedName.equalsAscii( ELEMENT_FILE_ENTRY ) )
114cdf0e10cSrcweir 	{
11576bf0a21SHerbert Dürr 		setProperty( PKG_MNFST_FULLPATH, aConvertedAttribs[sFullPathAttribute]);
11676bf0a21SHerbert Dürr 		setProperty( PKG_MNFST_MEDIATYPE, aConvertedAttribs[sMediaTypeAttribute]);
117cdf0e10cSrcweir 
11876bf0a21SHerbert Dürr 		const OUString& sVersion = aConvertedAttribs[sVersionAttribute];
119cdf0e10cSrcweir         if ( sVersion.getLength() )
12076bf0a21SHerbert Dürr        		setProperty( PKG_MNFST_VERSION, sVersion );
121cdf0e10cSrcweir 
12276bf0a21SHerbert Dürr 		const OUString& sSize = aConvertedAttribs[sSizeAttribute];
123cdf0e10cSrcweir 		if ( sSize.getLength() )
12476bf0a21SHerbert Dürr        		setProperty( PKG_MNFST_UCOMPSIZE, sSize.toInt32() );
125cdf0e10cSrcweir 	}
126cdf0e10cSrcweir 	else if ( aStack.size() > 1 )
127cdf0e10cSrcweir 	{
128cdf0e10cSrcweir         ManifestStack::reverse_iterator aIter = aStack.rbegin();
129cdf0e10cSrcweir         aIter++;
130cdf0e10cSrcweir 
13176bf0a21SHerbert Dürr 		if ( aIter->m_aConvertedName.equalsAscii( ELEMENT_FILE_ENTRY ) )
132cdf0e10cSrcweir         {
13376bf0a21SHerbert Dürr             if ( aConvertedName.equalsAscii( ELEMENT_ENCRYPTION_DATA ) )
134cdf0e10cSrcweir             {
135cdf0e10cSrcweir                 // If this element exists, then this stream is encrypted and we need
136cdf0e10cSrcweir                 // to import the initialisation vector, salt and iteration count used
137cdf0e10cSrcweir                 nDerivedKeySize = 0;
138cdf0e10cSrcweir                 if ( !bIgnoreEncryptData )
139cdf0e10cSrcweir                 {
14076bf0a21SHerbert Dürr                 	long nDigestId = 0;
14176bf0a21SHerbert Dürr                     const OUString& rChecksumType = aConvertedAttribs[sChecksumTypeAttribute];
14276bf0a21SHerbert Dürr                     if( rChecksumType.equalsAscii( SHA1_1K_NAME )
14376bf0a21SHerbert Dürr                     ||  rChecksumType.equalsAscii( SHA1_1K_URL ) )
14476bf0a21SHerbert Dürr        		            nDigestId = xml::crypto::DigestID::SHA1_1K;
14576bf0a21SHerbert Dürr                     else if ( rChecksumType.equalsAscii( SHA256_1K_URL ) )
14676bf0a21SHerbert Dürr        		            nDigestId = xml::crypto::DigestID::SHA256_1K;
147cdf0e10cSrcweir                     else
14876bf0a21SHerbert Dürr                         bIgnoreEncryptData = true;
149cdf0e10cSrcweir 
150cdf0e10cSrcweir                     if ( !bIgnoreEncryptData )
151cdf0e10cSrcweir                     {
15276bf0a21SHerbert Dürr                         setProperty( PKG_MNFST_DIGESTALG, nDigestId );
15376bf0a21SHerbert Dürr                         const OUString& sChecksumData = aConvertedAttribs[sChecksumAttribute];
154cdf0e10cSrcweir                         uno::Sequence < sal_Int8 > aDecodeBuffer;
15576bf0a21SHerbert Dürr                         Base64Codec::decodeBase64( aDecodeBuffer, sChecksumData );
15676bf0a21SHerbert Dürr                         setProperty( PKG_MNFST_DIGEST, aDecodeBuffer );
157cdf0e10cSrcweir                     }
158cdf0e10cSrcweir                 }
159cdf0e10cSrcweir             }
160cdf0e10cSrcweir         }
161*bf9149e6SHerbert Dürr         else if ( aIter->m_aConvertedName.equalsAscii( ELEMENT_ENCRYPTION_DATA ) )
162cdf0e10cSrcweir         {
16376bf0a21SHerbert Dürr             if ( aConvertedName.equalsAscii( ELEMENT_ALGORITHM ) )
164cdf0e10cSrcweir             {
165cdf0e10cSrcweir                 if ( !bIgnoreEncryptData )
166cdf0e10cSrcweir                 {
16776bf0a21SHerbert Dürr                     long nCypherId = 0;
16876bf0a21SHerbert Dürr                     const OUString& rAlgoName = aConvertedAttribs[sAlgorithmNameAttribute];
16976bf0a21SHerbert Dürr                     if ( rAlgoName.equalsAscii( BLOWFISH_NAME )
17076bf0a21SHerbert Dürr                     ||   rAlgoName.equalsAscii( BLOWFISH_URL ) )
17176bf0a21SHerbert Dürr                     	 nCypherId = xml::crypto::CipherID::BLOWFISH_CFB_8;
17276bf0a21SHerbert Dürr                     else if( rAlgoName.equalsAscii( AES256_URL ) )
173cdf0e10cSrcweir                     {
17476bf0a21SHerbert Dürr                     	 nCypherId = xml::crypto::CipherID::AES_CBC_W3C_PADDING;
175cdf0e10cSrcweir                         OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 32, "Unexpected derived key length!" );
176cdf0e10cSrcweir                         nDerivedKeySize = 32;
177cdf0e10cSrcweir                     }
17876bf0a21SHerbert Dürr                     else if( rAlgoName.equalsAscii( AES192_URL ) )
179cdf0e10cSrcweir                     {
18076bf0a21SHerbert Dürr                     	 nCypherId = xml::crypto::CipherID::AES_CBC_W3C_PADDING;
181cdf0e10cSrcweir                         OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 24, "Unexpected derived key length!" );
182cdf0e10cSrcweir                         nDerivedKeySize = 24;
183cdf0e10cSrcweir                     }
18476bf0a21SHerbert Dürr                     else if( rAlgoName.equalsAscii( AES128_URL ) )
185cdf0e10cSrcweir                     {
18676bf0a21SHerbert Dürr                     	 nCypherId = xml::crypto::CipherID::AES_CBC_W3C_PADDING;
187cdf0e10cSrcweir                         OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 16, "Unexpected derived key length!" );
188cdf0e10cSrcweir                         nDerivedKeySize = 16;
189cdf0e10cSrcweir                     }
190cdf0e10cSrcweir                     else
19176bf0a21SHerbert Dürr                         bIgnoreEncryptData = true;
192cdf0e10cSrcweir 
193cdf0e10cSrcweir                     if ( !bIgnoreEncryptData )
194cdf0e10cSrcweir                     {
19576bf0a21SHerbert Dürr                     	 setProperty( PKG_MNFST_ENCALG, nCypherId );
19676bf0a21SHerbert Dürr                         const OUString& sInitVector = aConvertedAttribs[sInitialisationVectorAttribute];
197cdf0e10cSrcweir                         uno::Sequence < sal_Int8 > aDecodeBuffer;
19876bf0a21SHerbert Dürr                         Base64Codec::decodeBase64 ( aDecodeBuffer, sInitVector );
19976bf0a21SHerbert Dürr                     	 setProperty( PKG_MNFST_INIVECTOR, aDecodeBuffer );
200cdf0e10cSrcweir                     }
201cdf0e10cSrcweir                 }
202cdf0e10cSrcweir             }
20376bf0a21SHerbert Dürr             else if ( aConvertedName.equalsAscii( ELEMENT_KEY_DERIVATION ) )
204cdf0e10cSrcweir             {
205cdf0e10cSrcweir                 if ( !bIgnoreEncryptData )
206cdf0e10cSrcweir                 {
20776bf0a21SHerbert Dürr                     const OUString& rKeyDerivString = aConvertedAttribs[sKeyDerivationNameAttribute];
20876bf0a21SHerbert Dürr                     if ( rKeyDerivString.equalsAscii( PBKDF2_NAME ) || rKeyDerivString.equalsAscii( PBKDF2_URL ) )
209cdf0e10cSrcweir                     {
21076bf0a21SHerbert Dürr                         const OUString& rSaltString = aConvertedAttribs[sSaltAttribute];
211cdf0e10cSrcweir                         uno::Sequence < sal_Int8 > aDecodeBuffer;
21276bf0a21SHerbert Dürr                         Base64Codec::decodeBase64 ( aDecodeBuffer, rSaltString );
21376bf0a21SHerbert Dürr                     	 setProperty( PKG_MNFST_SALT, aDecodeBuffer );
214cdf0e10cSrcweir 
21576bf0a21SHerbert Dürr                         const OUString& rIterationCount = aConvertedAttribs[sIterationCountAttribute];
21676bf0a21SHerbert Dürr                         setProperty( PKG_MNFST_ITERATION, rIterationCount.toInt32() );
217cdf0e10cSrcweir 
21876bf0a21SHerbert Dürr                         const OUString& rKeySize = aConvertedAttribs[sKeySizeAttribute];
21976bf0a21SHerbert Dürr                         if ( rKeySize.getLength() )
220cdf0e10cSrcweir                         {
22176bf0a21SHerbert Dürr                             const sal_Int32 nKey = rKeySize.toInt32();
222cdf0e10cSrcweir                             OSL_ENSURE( !nDerivedKeySize || nKey == nDerivedKeySize , "Provided derived key length differs from the expected one!" );
223cdf0e10cSrcweir                             nDerivedKeySize = nKey;
224cdf0e10cSrcweir                         }
225cdf0e10cSrcweir                         else if ( !nDerivedKeySize )
226cdf0e10cSrcweir                             nDerivedKeySize = 16;
227cdf0e10cSrcweir                         else if ( nDerivedKeySize != 16 )
228cdf0e10cSrcweir                             OSL_ENSURE( sal_False, "Default derived key length differs from the expected one!" );
229cdf0e10cSrcweir 
23076bf0a21SHerbert Dürr                         setProperty( PKG_MNFST_DERKEYSIZE, nDerivedKeySize );
231cdf0e10cSrcweir                     }
232cdf0e10cSrcweir                     else
23376bf0a21SHerbert Dürr                         bIgnoreEncryptData = true;
234cdf0e10cSrcweir                 }
235cdf0e10cSrcweir             }
23676bf0a21SHerbert Dürr             else if ( aConvertedName.equalsAscii( ELEMENT_START_KEY_GENERATION ) )
237cdf0e10cSrcweir             {
23876bf0a21SHerbert Dürr                 const OUString& rSKeyAlg = aConvertedAttribs[sStartKeyAlgNameAttribute];
23976bf0a21SHerbert Dürr                 if ( rSKeyAlg.equalsAscii( SHA256_URL ) )
24076bf0a21SHerbert Dürr                 	setProperty( PKG_MNFST_STARTALG, xml::crypto::DigestID::SHA256 );
24176bf0a21SHerbert Dürr                 else if ( rSKeyAlg.equalsAscii( SHA1_NAME ) || rSKeyAlg.equalsAscii( SHA1_URL ) )
24276bf0a21SHerbert Dürr                 	setProperty( PKG_MNFST_STARTALG, xml::crypto::DigestID::SHA1 );
243cdf0e10cSrcweir                 else
24476bf0a21SHerbert Dürr                     bIgnoreEncryptData = true;
245cdf0e10cSrcweir             }
246cdf0e10cSrcweir         }
247cdf0e10cSrcweir 	}
248cdf0e10cSrcweir }
249cdf0e10cSrcweir 
250cdf0e10cSrcweir // ---------------------------------------------------
251cdf0e10cSrcweir void SAL_CALL ManifestImport::endElement( const OUString& aName )
252cdf0e10cSrcweir 	throw( xml::sax::SAXException, uno::RuntimeException )
253cdf0e10cSrcweir {
25476bf0a21SHerbert Dürr 	if( aStack.empty() )
25576bf0a21SHerbert Dürr 		return;
25676bf0a21SHerbert Dürr 
25776bf0a21SHerbert Dürr 	const OUString aConvertedName = ConvertName( aName );
25876bf0a21SHerbert Dürr 	if( !aStack.rbegin()->m_aConvertedName.equals( aConvertedName ) )
25976bf0a21SHerbert Dürr 		return;
26076bf0a21SHerbert Dürr 
26176bf0a21SHerbert Dürr 	aStack.pop_back();
262*bf9149e6SHerbert Dürr 
263*bf9149e6SHerbert Dürr 	if( !aConvertedName.equalsAscii( ELEMENT_FILE_ENTRY ) )
264*bf9149e6SHerbert Dürr 		return;
26576bf0a21SHerbert Dürr 
26676bf0a21SHerbert Dürr 	// create the property sequence
26776bf0a21SHerbert Dürr 	// Put full-path property first for MBA
26876bf0a21SHerbert Dürr 	// TODO: get rid of fullpath-first requirement
26976bf0a21SHerbert Dürr 	const bool bHasFullPath = maValues[PKG_MNFST_FULLPATH].hasValue();
27076bf0a21SHerbert Dürr 	OSL_ENSURE( bHasFullPath, "Full path missing in manifest" );
27176bf0a21SHerbert Dürr 
27276bf0a21SHerbert Dürr 	int nNumProperty = bHasFullPath ? 1 : 0;
27376bf0a21SHerbert Dürr 	PropertyValue aProperties[ PKG_SIZE_ENCR_MNFST ];
27476bf0a21SHerbert Dürr 	for( int i = 0; i < PKG_SIZE_ENCR_MNFST; ++i)
27576bf0a21SHerbert Dürr 	{
27676bf0a21SHerbert Dürr 		if(! maValues[i].hasValue() )
27776bf0a21SHerbert Dürr 			continue;
27876bf0a21SHerbert Dürr 
27976bf0a21SHerbert Dürr 		const int nDest = (i == PKG_MNFST_FULLPATH) ? 0 : nNumProperty++;
28076bf0a21SHerbert Dürr 		PropertyValue& rProp = aProperties[ nDest ];
28176bf0a21SHerbert Dürr 		rProp.Name = OUString::createFromAscii( getMnfstPropName(i));
28276bf0a21SHerbert Dürr 		rProp.Value = maValues[i];
28376bf0a21SHerbert Dürr 		maValues[i].clear();
284cdf0e10cSrcweir 	}
28576bf0a21SHerbert Dürr 
28676bf0a21SHerbert Dürr 	// add the property sequence to the vector of manifests
28776bf0a21SHerbert Dürr 	rManVector.push_back ( PropertyValues( aProperties, nNumProperty ) );
28876bf0a21SHerbert Dürr 	bIgnoreEncryptData = false;
289cdf0e10cSrcweir }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir // ---------------------------------------------------
292cdf0e10cSrcweir void SAL_CALL ManifestImport::characters( const OUString& /*aChars*/ )
293cdf0e10cSrcweir 		throw( xml::sax::SAXException, uno::RuntimeException )
294cdf0e10cSrcweir {
295cdf0e10cSrcweir }
296cdf0e10cSrcweir 
297cdf0e10cSrcweir // ---------------------------------------------------
298cdf0e10cSrcweir void SAL_CALL ManifestImport::ignorableWhitespace( const OUString& /*aWhitespaces*/ )
299cdf0e10cSrcweir 		throw( xml::sax::SAXException, uno::RuntimeException )
300cdf0e10cSrcweir {
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir // ---------------------------------------------------
304cdf0e10cSrcweir void SAL_CALL ManifestImport::processingInstruction( const OUString& /*aTarget*/, const OUString& /*aData*/ )
305cdf0e10cSrcweir 		throw( xml::sax::SAXException, uno::RuntimeException )
306cdf0e10cSrcweir {
307cdf0e10cSrcweir }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir // ---------------------------------------------------
310cdf0e10cSrcweir void SAL_CALL ManifestImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
311cdf0e10cSrcweir 		throw( xml::sax::SAXException, uno::RuntimeException )
312cdf0e10cSrcweir {
313cdf0e10cSrcweir }
314cdf0e10cSrcweir 
315cdf0e10cSrcweir // ---------------------------------------------------
316cdf0e10cSrcweir ::rtl::OUString ManifestImport::PushNameAndNamespaces( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs, StringHashMap& o_aConvertedAttribs )
317cdf0e10cSrcweir {
318cdf0e10cSrcweir     StringHashMap aNamespaces;
319cdf0e10cSrcweir     ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > aAttribsStrs;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir     if ( xAttribs.is() )
322cdf0e10cSrcweir     {
323cdf0e10cSrcweir 	    sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0;
324cdf0e10cSrcweir         aAttribsStrs.reserve( nAttrCount );
325cdf0e10cSrcweir 
326cdf0e10cSrcweir 	    for( sal_Int16 nInd = 0; nInd < nAttrCount; nInd++ )
327cdf0e10cSrcweir 	    {
328cdf0e10cSrcweir 		    ::rtl::OUString aAttrName = xAttribs->getNameByIndex( nInd );
329cdf0e10cSrcweir             ::rtl::OUString aAttrValue = xAttribs->getValueByIndex( nInd );
330cdf0e10cSrcweir             if ( aAttrName.getLength() >= 5
331cdf0e10cSrcweir               && aAttrName.compareToAscii( "xmlns", 5 ) == 0
332cdf0e10cSrcweir               && ( aAttrName.getLength() == 5 || aAttrName.getStr()[5] == ( sal_Unicode )':' ) )
333cdf0e10cSrcweir             {
334cdf0e10cSrcweir                 // this is a namespace declaration
335cdf0e10cSrcweir                 ::rtl::OUString aNsName( ( aAttrName.getLength() == 5 ) ? ::rtl::OUString() : aAttrName.copy( 6 ) );
336cdf0e10cSrcweir                 aNamespaces[aNsName] = aAttrValue;
337cdf0e10cSrcweir             }
338cdf0e10cSrcweir             else
339cdf0e10cSrcweir             {
340cdf0e10cSrcweir                 // this is no namespace declaration
341cdf0e10cSrcweir                 aAttribsStrs.push_back( pair< ::rtl::OUString, ::rtl::OUString >( aAttrName, aAttrValue ) );
342cdf0e10cSrcweir             }
343cdf0e10cSrcweir         }
344cdf0e10cSrcweir     }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir     ::rtl::OUString aConvertedName = ConvertNameWithNamespace( aName, aNamespaces );
347cdf0e10cSrcweir     if ( !aConvertedName.getLength() )
348cdf0e10cSrcweir         aConvertedName = ConvertName( aName );
349cdf0e10cSrcweir 
350cdf0e10cSrcweir     aStack.push_back( ManifestScopeEntry( aConvertedName, aNamespaces ) );
351cdf0e10cSrcweir 
352cdf0e10cSrcweir     for ( sal_uInt16 nInd = 0; nInd < aAttribsStrs.size(); nInd++ )
353cdf0e10cSrcweir     {
354cdf0e10cSrcweir         // convert the attribute names on filling
355cdf0e10cSrcweir         o_aConvertedAttribs[ConvertName( aAttribsStrs[nInd].first )] = aAttribsStrs[nInd].second;
356cdf0e10cSrcweir     }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     return aConvertedName;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir 
36176bf0a21SHerbert Dürr 
362cdf0e10cSrcweir // ---------------------------------------------------
363cdf0e10cSrcweir ::rtl::OUString ManifestImport::ConvertNameWithNamespace( const ::rtl::OUString& aName, const StringHashMap& aNamespaces )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir     ::rtl::OUString aNsAlias;
366cdf0e10cSrcweir     ::rtl::OUString aPureName = aName;
367cdf0e10cSrcweir 
368cdf0e10cSrcweir     sal_Int32 nInd = aName.indexOf( ( sal_Unicode )':' );
369cdf0e10cSrcweir     if ( nInd != -1 && nInd < aName.getLength() )
370cdf0e10cSrcweir     {
371cdf0e10cSrcweir         aNsAlias = aName.copy( 0, nInd );
372cdf0e10cSrcweir         aPureName = aName.copy( nInd + 1 );
373cdf0e10cSrcweir     }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir     ::rtl::OUString aResult;
376cdf0e10cSrcweir 
377cdf0e10cSrcweir     StringHashMap::const_iterator aIter = aNamespaces.find( aNsAlias );
378cdf0e10cSrcweir     if ( aIter != aNamespaces.end()
37976bf0a21SHerbert Dürr       && ( aIter->second.equalsAscii( MANIFEST_NAMESPACE )
38076bf0a21SHerbert Dürr         || aIter->second.equalsAscii( MANIFEST_OASIS_NAMESPACE ) ) )
381cdf0e10cSrcweir     {
382cdf0e10cSrcweir         // no check for manifest.xml consistency currently since the old versions have supported inconsistent documents as well
383cdf0e10cSrcweir         aResult = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NSPREFIX ) );
384cdf0e10cSrcweir         aResult += aPureName;
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir     return aResult;
388cdf0e10cSrcweir }
389cdf0e10cSrcweir 
390cdf0e10cSrcweir // ---------------------------------------------------
391cdf0e10cSrcweir ::rtl::OUString ManifestImport::ConvertName( const ::rtl::OUString& aName )
392cdf0e10cSrcweir {
393cdf0e10cSrcweir     ::rtl::OUString aConvertedName;
394cdf0e10cSrcweir     for ( ManifestStack::reverse_iterator aIter = aStack.rbegin(); !aConvertedName.getLength() && aIter != aStack.rend(); aIter++ )
395cdf0e10cSrcweir     {
396cdf0e10cSrcweir         if ( !aIter->m_aNamespaces.empty() )
397cdf0e10cSrcweir             aConvertedName = ConvertNameWithNamespace( aName, aIter->m_aNamespaces );
398cdf0e10cSrcweir     }
399cdf0e10cSrcweir 
400cdf0e10cSrcweir     if ( !aConvertedName.getLength() )
401cdf0e10cSrcweir         aConvertedName = aName;
402cdf0e10cSrcweir 
403cdf0e10cSrcweir     return aConvertedName;
404cdf0e10cSrcweir }
405cdf0e10cSrcweir 
406