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