1*ca5ec200SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*ca5ec200SAndrew Rist * distributed with this work for additional information 6*ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance 9*ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*ca5ec200SAndrew Rist * software distributed under the License is distributed on an 15*ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the 17*ca5ec200SAndrew Rist * specific language governing permissions and limitations 18*ca5ec200SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*ca5ec200SAndrew Rist *************************************************************/ 21*ca5ec200SAndrew Rist 22*ca5ec200SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "ooxmldocpropimport.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <vector> 27cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp> 28cdf0e10cSrcweir #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp> 29cdf0e10cSrcweir #include <com/sun/star/embed/XRelationshipAccess.hpp> 30cdf0e10cSrcweir #include <com/sun/star/embed/XStorage.hpp> 31cdf0e10cSrcweir #include "oox/core/fastparser.hxx" 32cdf0e10cSrcweir #include "oox/core/relations.hxx" 33cdf0e10cSrcweir #include "oox/helper/containerhelper.hxx" 34cdf0e10cSrcweir #include "oox/helper/helper.hxx" 35cdf0e10cSrcweir #include "docprophandler.hxx" 36cdf0e10cSrcweir 37cdf0e10cSrcweir namespace oox { 38cdf0e10cSrcweir namespace docprop { 39cdf0e10cSrcweir 40cdf0e10cSrcweir // ============================================================================ 41cdf0e10cSrcweir 42cdf0e10cSrcweir using namespace ::com::sun::star::beans; 43cdf0e10cSrcweir using namespace ::com::sun::star::document; 44cdf0e10cSrcweir using namespace ::com::sun::star::embed; 45cdf0e10cSrcweir using namespace ::com::sun::star::io; 46cdf0e10cSrcweir using namespace ::com::sun::star::lang; 47cdf0e10cSrcweir using namespace ::com::sun::star::uno; 48cdf0e10cSrcweir using namespace ::com::sun::star::xml::sax; 49cdf0e10cSrcweir 50cdf0e10cSrcweir using ::rtl::OUString; 51cdf0e10cSrcweir 52cdf0e10cSrcweir // ============================================================================ 53cdf0e10cSrcweir 54cdf0e10cSrcweir OUString SAL_CALL DocumentPropertiesImport_getImplementationName() 55cdf0e10cSrcweir { 56cdf0e10cSrcweir return CREATE_OUSTRING( "com.sun.star.comp.oox.docprop.DocumentPropertiesImporter" ); 57cdf0e10cSrcweir } 58cdf0e10cSrcweir 59cdf0e10cSrcweir Sequence< OUString > SAL_CALL DocumentPropertiesImport_getSupportedServiceNames() 60cdf0e10cSrcweir { 61cdf0e10cSrcweir Sequence< OUString > aServices( 1 ); 62cdf0e10cSrcweir aServices[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.OOXMLDocumentPropertiesImporter" ); 63cdf0e10cSrcweir return aServices; 64cdf0e10cSrcweir } 65cdf0e10cSrcweir 66cdf0e10cSrcweir Reference< XInterface > SAL_CALL DocumentPropertiesImport_createInstance( const Reference< XComponentContext >& rxContext ) SAL_THROW((Exception)) 67cdf0e10cSrcweir { 68cdf0e10cSrcweir return static_cast< ::cppu::OWeakObject* >( new DocumentPropertiesImport( rxContext ) ); 69cdf0e10cSrcweir } 70cdf0e10cSrcweir 71cdf0e10cSrcweir // ============================================================================ 72cdf0e10cSrcweir 73cdf0e10cSrcweir namespace { 74cdf0e10cSrcweir 75cdf0e10cSrcweir Sequence< InputSource > lclGetRelatedStreams( const Reference< XStorage >& rxStorage, const OUString& rStreamType ) throw (RuntimeException) 76cdf0e10cSrcweir { 77cdf0e10cSrcweir Reference< XRelationshipAccess > xRelation( rxStorage, UNO_QUERY_THROW ); 78cdf0e10cSrcweir Reference< XHierarchicalStorageAccess > xHierarchy( rxStorage, UNO_QUERY_THROW ); 79cdf0e10cSrcweir 80cdf0e10cSrcweir Sequence< Sequence< StringPair > > aPropsInfo = xRelation->getRelationshipsByType( rStreamType ); 81cdf0e10cSrcweir 82cdf0e10cSrcweir ::std::vector< InputSource > aResult; 83cdf0e10cSrcweir 84cdf0e10cSrcweir for( sal_Int32 nIndex = 0, nLength = aPropsInfo.getLength(); nIndex < nLength; ++nIndex ) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir const Sequence< StringPair >& rEntries = aPropsInfo[ nIndex ]; 87cdf0e10cSrcweir for( sal_Int32 nEntryIndex = 0, nEntryLength = rEntries.getLength(); nEntryIndex < nEntryLength; ++nEntryIndex ) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir const StringPair& rEntry = rEntries[ nEntryIndex ]; 90cdf0e10cSrcweir if( rEntry.First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) ) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir Reference< XExtendedStorageStream > xExtStream( 93cdf0e10cSrcweir xHierarchy->openStreamElementByHierarchicalName( rEntry.Second, ElementModes::READ ), UNO_QUERY_THROW ); 94cdf0e10cSrcweir Reference< XInputStream > xInStream = xExtStream->getInputStream(); 95cdf0e10cSrcweir if( xInStream.is() ) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir aResult.resize( aResult.size() + 1 ); 98cdf0e10cSrcweir aResult.back().sSystemId = rEntry.Second; 99cdf0e10cSrcweir aResult.back().aInputStream = xExtStream->getInputStream(); 100cdf0e10cSrcweir } 101cdf0e10cSrcweir break; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir } 104cdf0e10cSrcweir } 105cdf0e10cSrcweir 106cdf0e10cSrcweir return ContainerHelper::vectorToSequence( aResult ); 107cdf0e10cSrcweir } 108cdf0e10cSrcweir 109cdf0e10cSrcweir } // namespace 110cdf0e10cSrcweir 111cdf0e10cSrcweir // ============================================================================ 112cdf0e10cSrcweir 113cdf0e10cSrcweir DocumentPropertiesImport::DocumentPropertiesImport( const Reference< XComponentContext >& rxContext ) : 114cdf0e10cSrcweir mxContext( rxContext ) 115cdf0e10cSrcweir { 116cdf0e10cSrcweir } 117cdf0e10cSrcweir 118cdf0e10cSrcweir // XServiceInfo 119cdf0e10cSrcweir 120cdf0e10cSrcweir OUString SAL_CALL DocumentPropertiesImport::getImplementationName() throw (RuntimeException) 121cdf0e10cSrcweir { 122cdf0e10cSrcweir return DocumentPropertiesImport_getImplementationName(); 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir sal_Bool SAL_CALL DocumentPropertiesImport::supportsService( const OUString& rServiceName ) throw (RuntimeException) 126cdf0e10cSrcweir { 127cdf0e10cSrcweir Sequence< OUString > aServiceNames = DocumentPropertiesImport_getSupportedServiceNames(); 128cdf0e10cSrcweir for( sal_Int32 nIndex = 0, nLength = aServiceNames.getLength(); nIndex < nLength; ++nIndex ) 129cdf0e10cSrcweir if( aServiceNames[ nIndex ] == rServiceName ) 130cdf0e10cSrcweir return sal_True; 131cdf0e10cSrcweir return sal_False; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir Sequence< OUString > SAL_CALL DocumentPropertiesImport::getSupportedServiceNames() throw (RuntimeException) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir return DocumentPropertiesImport_getSupportedServiceNames(); 137cdf0e10cSrcweir } 138cdf0e10cSrcweir 139cdf0e10cSrcweir // XOOXMLDocumentPropertiesImporter 140cdf0e10cSrcweir 141cdf0e10cSrcweir void SAL_CALL DocumentPropertiesImport::importProperties( 142cdf0e10cSrcweir const Reference< XStorage >& rxSource, const Reference< XDocumentProperties >& rxDocumentProperties ) 143cdf0e10cSrcweir throw (RuntimeException, IllegalArgumentException, SAXException, Exception) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir if( !mxContext.is() ) 146cdf0e10cSrcweir throw RuntimeException(); 147cdf0e10cSrcweir 148cdf0e10cSrcweir if( !rxSource.is() || !rxDocumentProperties.is() ) 149cdf0e10cSrcweir throw IllegalArgumentException(); 150cdf0e10cSrcweir 151cdf0e10cSrcweir Sequence< InputSource > aCoreStreams = lclGetRelatedStreams( rxSource, CREATE_OFFICEDOC_RELATION_TYPE( "metadata/core-properties" ) ); 152cdf0e10cSrcweir // MS Office seems to have a bug, so we have to do similar handling 153cdf0e10cSrcweir if( !aCoreStreams.hasElements() ) 154cdf0e10cSrcweir aCoreStreams = lclGetRelatedStreams( rxSource, CREATE_PACKAGE_RELATION_TYPE( "metadata/core-properties" ) ); 155cdf0e10cSrcweir 156cdf0e10cSrcweir Sequence< InputSource > aExtStreams = lclGetRelatedStreams( rxSource, CREATE_OFFICEDOC_RELATION_TYPE( "extended-properties" ) ); 157cdf0e10cSrcweir Sequence< InputSource > aCustomStreams = lclGetRelatedStreams( rxSource, CREATE_OFFICEDOC_RELATION_TYPE( "custom-properties" ) ); 158cdf0e10cSrcweir 159cdf0e10cSrcweir if( aCoreStreams.hasElements() || aExtStreams.hasElements() || aCustomStreams.hasElements() ) 160cdf0e10cSrcweir { 161cdf0e10cSrcweir if( aCoreStreams.getLength() > 1 ) 162cdf0e10cSrcweir throw IOException( CREATE_OUSTRING( "Unexpected core properties stream!" ), Reference< XInterface >() ); 163cdf0e10cSrcweir 164cdf0e10cSrcweir ::oox::core::FastParser aParser( mxContext ); 165cdf0e10cSrcweir aParser.registerNamespace( NMSP_packageMetaCorePr ); 166cdf0e10cSrcweir aParser.registerNamespace( NMSP_dc ); 167cdf0e10cSrcweir aParser.registerNamespace( NMSP_dcTerms ); 168cdf0e10cSrcweir aParser.registerNamespace( NMSP_officeExtPr ); 169cdf0e10cSrcweir aParser.registerNamespace( NMSP_officeCustomPr ); 170cdf0e10cSrcweir aParser.registerNamespace( NMSP_officeDocPropsVT ); 171cdf0e10cSrcweir aParser.setDocumentHandler( new OOXMLDocPropHandler( mxContext, rxDocumentProperties ) ); 172cdf0e10cSrcweir 173cdf0e10cSrcweir if( aCoreStreams.hasElements() ) 174cdf0e10cSrcweir aParser.parseStream( aCoreStreams[ 0 ], true ); 175cdf0e10cSrcweir for( sal_Int32 nIndex = 0; nIndex < aExtStreams.getLength(); ++nIndex ) 176cdf0e10cSrcweir aParser.parseStream( aExtStreams[ nIndex ], true ); 177cdf0e10cSrcweir for( sal_Int32 nIndex = 0; nIndex < aCustomStreams.getLength(); ++nIndex ) 178cdf0e10cSrcweir aParser.parseStream( aCustomStreams[ nIndex ], true ); 179cdf0e10cSrcweir } 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir // ============================================================================ 183cdf0e10cSrcweir 184cdf0e10cSrcweir } // namespace docprop 185cdf0e10cSrcweir } // namespace oox 186