merge the formfield patch from ooo-build
[ooovba.git] / oox / source / docprop / ooxmldocpropimport.cxx
blob61335749d928baf76456eebdd7395c20718912d2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ooxmldocpropimport.cxx,v $
10 * $Revision: 1.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <com/sun/star/embed/XStorage.hpp>
32 #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
33 #include <com/sun/star/embed/XRelationshipAccess.hpp>
34 #include <com/sun/star/embed/ElementModes.hpp>
35 #include <com/sun/star/xml/sax/XFastParser.hpp>
36 #include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
37 #include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
39 #include <cppuhelper/factory.hxx>
40 #include <cppuhelper/implementationentry.hxx>
42 #include <oox/core/namespaces.hxx>
43 #include "docprophandler.hxx"
44 #include "ooxmldocpropimport.hxx"
46 using namespace ::com::sun::star;
48 namespace oox {
49 namespace docprop {
51 // -----------------------------------------------------------
52 ::rtl::OUString SAL_CALL OOXMLDocPropImportImpl_getImplementationName()
54 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
55 "com.sun.star.comp.oox.docprop.OOXMLDocumentPropertiesImporter"));
58 // -----------------------------------------------------------
59 uno::Sequence< ::rtl::OUString > SAL_CALL OOXMLDocPropImportImpl_getSupportedServiceNames()
61 uno::Sequence< ::rtl::OUString > s(1);
62 s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
63 "com.sun.star.document.OOXMLDocumentPropertiesImporter"));
64 return s;
67 // -----------------------------------------------------------
68 uno::Reference< uno::XInterface > SAL_CALL OOXMLDocPropImportImpl_createInstance(
69 const uno::Reference< uno::XComponentContext > & context)
70 SAL_THROW((uno::Exception))
72 return static_cast< ::cppu::OWeakObject * >(new OOXMLDocPropImportImpl(context));
76 // -----------------------------------------------------------
77 OOXMLDocPropImportImpl::OOXMLDocPropImportImpl(uno::Reference< uno::XComponentContext > const & xContext) :
78 m_xContext( xContext )
81 // -----------------------------------------------------------
82 uno::Sequence< xml::sax::InputSource > OOXMLDocPropImportImpl::GetRelatedStreams( const uno::Reference< embed::XStorage > xStorage, const ::rtl::OUString& aStreamType )
84 if ( !xStorage.is() )
85 throw uno::RuntimeException();
87 uno::Reference< embed::XRelationshipAccess > xRelation( xStorage, uno::UNO_QUERY_THROW );
88 uno::Reference< embed::XHierarchicalStorageAccess > xHierarchy( xStorage, uno::UNO_QUERY_THROW );
90 uno::Sequence< uno::Sequence< beans::StringPair > > aPropsInfo = xRelation->getRelationshipsByType( aStreamType );
92 sal_Int32 nLength = 0;
93 uno::Sequence< xml::sax::InputSource > aResult( aPropsInfo.getLength() );
94 if ( aPropsInfo.getLength() )
96 for ( sal_Int32 nInd = 0; nInd < aPropsInfo.getLength(); nInd++ )
97 for ( sal_Int32 nEntryInd = 0; nEntryInd < aPropsInfo[nInd].getLength(); nEntryInd++ )
98 if ( aPropsInfo[nInd][nEntryInd].First.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Target" ) ) ) )
100 uno::Reference< embed::XExtendedStorageStream > xExtStream = xHierarchy->openStreamElementByHierarchicalName( aPropsInfo[nInd][nEntryInd].Second, embed::ElementModes::READ );
101 if ( !xExtStream.is() )
102 throw uno::RuntimeException();
104 aResult[nLength].sSystemId = aPropsInfo[nInd][nEntryInd].Second;
105 aResult[nLength++].aInputStream = xExtStream->getInputStream();
106 break;
109 aResult.realloc( nLength );
112 return aResult;
115 // com.sun.star.uno.XServiceInfo:
116 // -----------------------------------------------------------
117 ::rtl::OUString SAL_CALL OOXMLDocPropImportImpl::getImplementationName() throw (uno::RuntimeException)
119 return OOXMLDocPropImportImpl_getImplementationName();
122 // -----------------------------------------------------------
123 ::sal_Bool SAL_CALL OOXMLDocPropImportImpl::supportsService(::rtl::OUString const & serviceName) throw (uno::RuntimeException)
125 uno::Sequence< ::rtl::OUString > serviceNames = OOXMLDocPropImportImpl_getSupportedServiceNames();
126 for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i)
128 if (serviceNames[i] == serviceName)
129 return sal_True;
132 return sal_False;
135 // -----------------------------------------------------------
136 uno::Sequence< ::rtl::OUString > SAL_CALL OOXMLDocPropImportImpl::getSupportedServiceNames() throw (uno::RuntimeException)
138 return OOXMLDocPropImportImpl_getSupportedServiceNames();
141 // -----------------------------------------------------------
142 // ::com::sun::star::document::XOOXMLDocumentPropertiesImporter:
143 void SAL_CALL OOXMLDocPropImportImpl::importProperties(const uno::Reference< embed::XStorage > & xSource, const uno::Reference< document::XDocumentProperties > & xDocumentProperties) throw (uno::RuntimeException, lang::IllegalArgumentException, xml::sax::SAXException, uno::Exception)
145 // TODO: Insert your implementation for "importProperties" here.
146 if ( !m_xContext.is() )
147 throw uno::RuntimeException();
149 if ( !xSource.is() || !xDocumentProperties.is() )
150 throw lang::IllegalArgumentException();
152 // the MS Office seems to have a bug, so we have to do similar handling
153 ::rtl::OUString aCoreType( RTL_CONSTASCII_USTRINGPARAM( "http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties" ) );
154 ::rtl::OUString aCoreWorkaroundType( RTL_CONSTASCII_USTRINGPARAM( "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" ) );
156 ::rtl::OUString aExtType( RTL_CONSTASCII_USTRINGPARAM( "http://schemas.openxmlformats.org/officedocument/2006/relationships/extended-properties" ) );
157 ::rtl::OUString aCustomType( RTL_CONSTASCII_USTRINGPARAM( "http://schemas.openxmlformats.org/officedocument/2006/relationships/custom-properties" ) );
159 uno::Sequence< xml::sax::InputSource > aCoreStreams = GetRelatedStreams( xSource, aCoreType );
160 if ( !aCoreStreams.getLength() )
161 aCoreStreams = GetRelatedStreams( xSource, aCoreWorkaroundType );
163 uno::Sequence< xml::sax::InputSource > aExtStreams = GetRelatedStreams( xSource, aExtType );
164 uno::Sequence< xml::sax::InputSource > aCustomStreams = GetRelatedStreams( xSource, aCustomType );
166 if ( aCoreStreams.getLength() || aExtStreams.getLength() || aCustomStreams.getLength() )
168 if ( aCoreStreams.getLength() > 1 )
169 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected core properties stream!" ) ), uno::Reference< uno::XInterface >() );
171 uno::Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_QUERY_THROW );
173 uno::Reference< xml::sax::XFastParser > xParser(
174 xFactory->createInstanceWithContext(
175 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.FastParser" ) ),
176 m_xContext ),
177 uno::UNO_QUERY_THROW );
179 uno::Reference< xml::sax::XFastTokenHandler > xTokenHandler(
180 xFactory->createInstanceWithContext(
181 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.oox.FastTokenHandlerService" ) ),
182 m_xContext ),
183 uno::UNO_QUERY_THROW );
185 uno::Reference< xml::sax::XFastDocumentHandler > xDocHandler( static_cast< xml::sax::XFastDocumentHandler* >( new OOXMLDocPropHandler( m_xContext, xDocumentProperties ) ) );
187 xParser->setFastDocumentHandler( xDocHandler );
188 xParser->setTokenHandler( xTokenHandler );
190 xParser->registerNamespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "http://schemas.openxmlformats.org/package/2006/metadata/core-properties" ) ), NMSP_COREPR );
191 xParser->registerNamespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "http://purl.org/dc/elements/1.1/" ) ), NMSP_DC );
192 xParser->registerNamespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "http://purl.org/dc/terms/" ) ), NMSP_DCTERMS );
193 xParser->registerNamespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" ) ), NMSP_EXTPR );
194 xParser->registerNamespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" ) ), NMSP_CUSTPR );
195 xParser->registerNamespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" ) ), NMSP_VT );
197 // #158414# XFastParser::parseStream() throws on invalid XML
198 if ( aCoreStreams.getLength() ) try
200 if ( aCoreStreams[0].aInputStream.is() )
202 xParser->parseStream( aCoreStreams[0] );
203 aCoreStreams[0].aInputStream->closeInput();
206 catch( uno::Exception& )
210 sal_Int32 nInd = 0;
211 for ( nInd = 0; nInd < aExtStreams.getLength(); nInd++ )
213 xParser->parseStream( aExtStreams[nInd] );
214 if ( aExtStreams[nInd].aInputStream.is() )
215 aExtStreams[nInd].aInputStream->closeInput();
218 for ( nInd = 0; nInd < aCustomStreams.getLength(); nInd++ )
220 xParser->parseStream( aCustomStreams[nInd] );
221 if ( aCustomStreams[nInd].aInputStream.is() )
222 aCustomStreams[nInd].aInputStream->closeInput();
227 } // namespace docprop
228 } // namespace oox