1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "ooxmldocpropimport.hxx"
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"
36 // ============================================================================
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
;
47 // ============================================================================
49 OUString SAL_CALL
DocumentPropertiesImport_getImplementationName()
51 return OUString( "com.sun.star.comp.oox.docprop.DocumentPropertiesImporter" );
54 Sequence
< OUString
> SAL_CALL
DocumentPropertiesImport_getSupportedServiceNames()
56 Sequence
< OUString
> aServices( 1 );
57 aServices
[ 0 ] = "com.sun.star.document.OOXMLDocumentPropertiesImporter";
61 Reference
< XInterface
> SAL_CALL
DocumentPropertiesImport_createInstance( const Reference
< XComponentContext
>& rxContext
) SAL_THROW((Exception
))
63 return static_cast< ::cppu::OWeakObject
* >( new DocumentPropertiesImport( rxContext
) );
66 // ============================================================================
70 Sequence
< InputSource
> lclGetRelatedStreams( const Reference
< XStorage
>& rxStorage
, const OUString
& rStreamType
) throw (RuntimeException
)
72 Reference
< XRelationshipAccess
> xRelation( rxStorage
, UNO_QUERY_THROW
);
73 Reference
< XHierarchicalStorageAccess
> xHierarchy( rxStorage
, UNO_QUERY_THROW
);
75 Sequence
< Sequence
< StringPair
> > aPropsInfo
= xRelation
->getRelationshipsByType( rStreamType
);
77 ::std::vector
< InputSource
> aResult
;
79 for( sal_Int32 nIndex
= 0, nLength
= aPropsInfo
.getLength(); nIndex
< nLength
; ++nIndex
)
81 const Sequence
< StringPair
>& rEntries
= aPropsInfo
[ nIndex
];
82 for( sal_Int32 nEntryIndex
= 0, nEntryLength
= rEntries
.getLength(); nEntryIndex
< nEntryLength
; ++nEntryIndex
)
84 const StringPair
& rEntry
= rEntries
[ nEntryIndex
];
85 if ( rEntry
.First
== "Target" )
87 Reference
< XExtendedStorageStream
> xExtStream(
88 xHierarchy
->openStreamElementByHierarchicalName( rEntry
.Second
, ElementModes::READ
), UNO_QUERY_THROW
);
89 Reference
< XInputStream
> xInStream
= xExtStream
->getInputStream();
92 aResult
.resize( aResult
.size() + 1 );
93 aResult
.back().sSystemId
= rEntry
.Second
;
94 aResult
.back().aInputStream
= xExtStream
->getInputStream();
101 return ContainerHelper::vectorToSequence( aResult
);
106 // ============================================================================
108 DocumentPropertiesImport::DocumentPropertiesImport( const Reference
< XComponentContext
>& rxContext
) :
109 mxContext( rxContext
)
115 OUString SAL_CALL
DocumentPropertiesImport::getImplementationName() throw (RuntimeException
)
117 return DocumentPropertiesImport_getImplementationName();
120 sal_Bool SAL_CALL
DocumentPropertiesImport::supportsService( const OUString
& rServiceName
) throw (RuntimeException
)
122 Sequence
< OUString
> aServiceNames
= DocumentPropertiesImport_getSupportedServiceNames();
123 for( sal_Int32 nIndex
= 0, nLength
= aServiceNames
.getLength(); nIndex
< nLength
; ++nIndex
)
124 if( aServiceNames
[ nIndex
] == rServiceName
)
129 Sequence
< OUString
> SAL_CALL
DocumentPropertiesImport::getSupportedServiceNames() throw (RuntimeException
)
131 return DocumentPropertiesImport_getSupportedServiceNames();
134 // XOOXMLDocumentPropertiesImporter
136 void SAL_CALL
DocumentPropertiesImport::importProperties(
137 const Reference
< XStorage
>& rxSource
, const Reference
< XDocumentProperties
>& rxDocumentProperties
)
138 throw (RuntimeException
, IllegalArgumentException
, SAXException
, Exception
)
140 if( !mxContext
.is() )
141 throw RuntimeException();
143 if( !rxSource
.is() || !rxDocumentProperties
.is() )
144 throw IllegalArgumentException();
146 Sequence
< InputSource
> aCoreStreams
= lclGetRelatedStreams( rxSource
, CREATE_OFFICEDOC_RELATION_TYPE( "metadata/core-properties" ) );
147 // MS Office seems to have a bug, so we have to do similar handling
148 if( !aCoreStreams
.hasElements() )
149 aCoreStreams
= lclGetRelatedStreams( rxSource
, CREATE_PACKAGE_RELATION_TYPE( "metadata/core-properties" ) );
151 Sequence
< InputSource
> aExtStreams
= lclGetRelatedStreams( rxSource
, CREATE_OFFICEDOC_RELATION_TYPE( "extended-properties" ) );
152 Sequence
< InputSource
> aCustomStreams
= lclGetRelatedStreams( rxSource
, CREATE_OFFICEDOC_RELATION_TYPE( "custom-properties" ) );
154 if( aCoreStreams
.hasElements() || aExtStreams
.hasElements() || aCustomStreams
.hasElements() )
156 if( aCoreStreams
.getLength() > 1 )
157 throw IOException( "Unexpected core properties stream!", Reference
< XInterface
>() );
159 ::oox::core::FastParser
aParser( mxContext
);
160 aParser
.registerNamespace( NMSP_packageMetaCorePr
);
161 aParser
.registerNamespace( NMSP_dc
);
162 aParser
.registerNamespace( NMSP_dcTerms
);
163 aParser
.registerNamespace( NMSP_officeExtPr
);
164 aParser
.registerNamespace( NMSP_officeCustomPr
);
165 aParser
.registerNamespace( NMSP_officeDocPropsVT
);
166 aParser
.setDocumentHandler( new OOXMLDocPropHandler( mxContext
, rxDocumentProperties
) );
168 if( aCoreStreams
.hasElements() )
169 aParser
.parseStream( aCoreStreams
[ 0 ], true );
170 for( sal_Int32 nIndex
= 0; nIndex
< aExtStreams
.getLength(); ++nIndex
)
171 aParser
.parseStream( aExtStreams
[ nIndex
], true );
172 for( sal_Int32 nIndex
= 0; nIndex
< aCustomStreams
.getLength(); ++nIndex
)
173 aParser
.parseStream( aCustomStreams
[ nIndex
], true );
177 // ============================================================================
179 } // namespace docprop
182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */