diff options
Diffstat (limited to 'xmloff/source/meta')
-rw-r--r-- | xmloff/source/meta/MetaExportComponent.cxx | 258 | ||||
-rw-r--r-- | xmloff/source/meta/MetaImportComponent.cxx | 118 | ||||
-rw-r--r-- | xmloff/source/meta/makefile.mk | 53 | ||||
-rw-r--r-- | xmloff/source/meta/xmlmetae.cxx | 526 | ||||
-rw-r--r-- | xmloff/source/meta/xmlmetai.cxx | 277 | ||||
-rw-r--r-- | xmloff/source/meta/xmlversion.cxx | 541 |
6 files changed, 1773 insertions, 0 deletions
diff --git a/xmloff/source/meta/MetaExportComponent.cxx b/xmloff/source/meta/MetaExportComponent.cxx new file mode 100644 index 000000000000..772d5907bd91 --- /dev/null +++ b/xmloff/source/meta/MetaExportComponent.cxx @@ -0,0 +1,258 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" +#include "MetaExportComponent.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Reference.hxx> + +#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP +#include <com/sun/star/uno/Exception.hpp> +#endif +#include <com/sun/star/beans/PropertyAttribute.hpp> + +// #110680# +//#ifndef _COMPHELPER_PROCESSFACTORY_HXX_ +//#include <comphelper/processfactory.hxx> +//#endif +#include <comphelper/genericpropertyset.hxx> +#include <rtl/ustrbuf.hxx> +#include "xmlnmspe.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlmetae.hxx> +#include "PropertySetMerger.hxx" +#include <tools/debug.hxx> + +#include <unotools/docinfohelper.hxx> + + +using namespace ::com::sun::star; +using namespace ::xmloff::token; + +// #110680# +XMLMetaExportComponent::XMLMetaExportComponent( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + sal_uInt16 nFlags ) +: SvXMLExport( xServiceFactory, MAP_INCH, XML_TEXT, nFlags ) +{ +} + +XMLMetaExportComponent::~XMLMetaExportComponent() +{ +} + +void SAL_CALL XMLMetaExportComponent::setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + try + { + SvXMLExport::setSourceDocument( xDoc ); + } + catch( lang::IllegalArgumentException& ) + { + // allow to use document properties service without model access + // this is required for document properties exporter + mxDocProps = + uno::Reference< document::XDocumentProperties >::query( xDoc ); + if( !mxDocProps.is() ) + throw lang::IllegalArgumentException(); + } +} + +sal_uInt32 XMLMetaExportComponent::exportDoc( enum XMLTokenEnum ) +{ + uno::Reference< xml::sax::XDocumentHandler > xDocHandler = GetDocHandler(); + + if( (getExportFlags() & EXPORT_OASIS) == 0 ) + { + uno::Reference< lang::XMultiServiceFactory > xFactory = getServiceFactory(); + if( xFactory.is() ) + { + try + { + ::comphelper::PropertyMapEntry aInfoMap[] = + { + { "Class", sizeof("Class")-1, 0, + &::getCppuType((::rtl::OUString*)0), + beans::PropertyAttribute::MAYBEVOID, 0}, + { NULL, 0, 0, NULL, 0, 0 } + }; + uno::Reference< beans::XPropertySet > xConvPropSet( + ::comphelper::GenericPropertySet_CreateInstance( + new ::comphelper::PropertySetInfo( aInfoMap ) ) ); + + uno::Any aAny; + aAny <<= GetXMLToken( XML_TEXT ); + xConvPropSet->setPropertyValue( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Class")), aAny ); + + uno::Reference< beans::XPropertySet > xPropSet = + getExportInfo().is() + ? PropertySetMerger_CreateInstance( getExportInfo(), + xConvPropSet ) + : getExportInfo(); + + uno::Sequence< uno::Any > aArgs( 3 ); + aArgs[0] <<= xDocHandler; + aArgs[1] <<= xPropSet; + aArgs[2] <<= GetModel(); + + // get filter component + xDocHandler = uno::Reference< xml::sax::XDocumentHandler >( + xFactory->createInstanceWithArguments( + ::rtl::OUString::createFromAscii("com.sun.star.comp.Oasis2OOoTransformer"), + aArgs), + uno::UNO_QUERY_THROW ); + + SetDocHandler( xDocHandler ); + } + catch( com::sun::star::uno::Exception& ) + { + OSL_ENSURE( sal_False, "Cannot instantiate com.sun.star.comp.Oasis2OOoTransformer!\n"); + } + } + } + + + xDocHandler->startDocument(); + { +#if 0 + GetAttrList().AddAttribute( + GetNamespaceMap().GetAttrNameByKey( XML_NAMESPACE_DC ), + GetNamespaceMap().GetNameByKey( XML_NAMESPACE_DC ) ); + GetAttrList().AddAttribute( + GetNamespaceMap().GetAttrNameByKey( XML_NAMESPACE_META ), + GetNamespaceMap().GetNameByKey( XML_NAMESPACE_META ) ); + GetAttrList().AddAttribute( + GetNamespaceMap().GetAttrNameByKey( XML_NAMESPACE_OFFICE ), + GetNamespaceMap().GetNameByKey( XML_NAMESPACE_OFFICE ) ); +#else + const SvXMLNamespaceMap& rMap = GetNamespaceMap(); + sal_uInt16 nPos = rMap.GetFirstKey(); + while( USHRT_MAX != nPos ) + { + GetAttrList().AddAttribute( rMap.GetAttrNameByKey( nPos ), rMap.GetNameByKey( nPos ) ); + nPos = GetNamespaceMap().GetNextKey( nPos ); + } +#endif + + const sal_Char* pVersion = 0; + switch( getDefaultVersion() ) + { + case SvtSaveOptions::ODFVER_LATEST: pVersion = "1.2"; break; + case SvtSaveOptions::ODFVER_012: pVersion = "1.2"; break; + case SvtSaveOptions::ODFVER_011: pVersion = "1.1"; break; + case SvtSaveOptions::ODFVER_010: break; + + default: + DBG_ERROR("xmloff::XMLMetaExportComponent::exportDoc(), unexpected odf default version!"); + } + + if( pVersion ) + AddAttribute( XML_NAMESPACE_OFFICE, XML_VERSION, + ::rtl::OUString::createFromAscii(pVersion) ); + + SvXMLElementExport aDocElem( *this, XML_NAMESPACE_OFFICE, XML_DOCUMENT_META, + sal_True, sal_True ); + + // NB: office:meta is now written by _ExportMeta + _ExportMeta(); + } + xDocHandler->endDocument(); + return 0; +} + +void XMLMetaExportComponent::_ExportMeta() +{ + if (mxDocProps.is()) { + ::rtl::OUString generator( ::utl::DocInfoHelper::GetGeneratorString() ); + // update generator here + mxDocProps->setGenerator(generator); + SvXMLMetaExport * pMeta = new SvXMLMetaExport(*this, mxDocProps); + uno::Reference<xml::sax::XDocumentHandler> xMeta(pMeta); + pMeta->Export(); + } else { + SvXMLExport::_ExportMeta(); + } +} + +// methods without content: +void XMLMetaExportComponent::_ExportAutoStyles() {} +void XMLMetaExportComponent::_ExportMasterStyles() {} +void XMLMetaExportComponent::_ExportContent() {} + + +uno::Sequence< rtl::OUString > SAL_CALL XMLMetaExportComponent_getSupportedServiceNames() + throw() +{ + const rtl::OUString aServiceName( + RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.XMLOasisMetaExporter" ) ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +rtl::OUString SAL_CALL XMLMetaExportComponent_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLMetaExportComponent" ) ); +} + +uno::Reference< uno::XInterface > SAL_CALL XMLMetaExportComponent_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr) + throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new XMLMetaExportComponent; + return (cppu::OWeakObject*)new XMLMetaExportComponent(rSMgr, EXPORT_META|EXPORT_OASIS); +} + +uno::Sequence< rtl::OUString > SAL_CALL XMLMetaExportOOO_getSupportedServiceNames() + throw() +{ + const rtl::OUString aServiceName( + RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.XMLMetaExporter" ) ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +rtl::OUString SAL_CALL XMLMetaExportOOO_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLMetaExportOOo" ) ); +} + +uno::Reference< uno::XInterface > SAL_CALL XMLMetaExportOOO_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr) + throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new XMLMetaExportComponent; + return (cppu::OWeakObject*)new XMLMetaExportComponent(rSMgr, EXPORT_META); +} + diff --git a/xmloff/source/meta/MetaImportComponent.cxx b/xmloff/source/meta/MetaImportComponent.cxx new file mode 100644 index 000000000000..b61e8d113042 --- /dev/null +++ b/xmloff/source/meta/MetaImportComponent.cxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "MetaImportComponent.hxx" +#include "xmlnmspe.hxx" + +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlmetai.hxx> +#include <xmloff/nmspmap.hxx> +#include <tools/string.hxx> + + +using namespace ::com::sun::star; +using namespace ::xmloff::token; + + +//=========================================================================== + +// #110680# +XMLMetaImportComponent::XMLMetaImportComponent( + const uno::Reference< lang::XMultiServiceFactory >& xServiceFactory) throw() + : SvXMLImport(xServiceFactory), mxDocProps() +{ +} + +XMLMetaImportComponent::~XMLMetaImportComponent() throw() +{ +} + + +SvXMLImportContext* XMLMetaImportComponent::CreateContext( + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const uno::Reference<xml::sax::XAttributeList > & xAttrList ) +{ + if ( (XML_NAMESPACE_OFFICE == nPrefix) && + IsXMLToken(rLocalName, XML_DOCUMENT_META) ) + { + if (!mxDocProps.is()) { + throw uno::RuntimeException(::rtl::OUString::createFromAscii( + "XMLMetaImportComponent::CreateContext: setTargetDocument " + "has not been called"), *this); + } + uno::Reference<xml::sax::XDocumentHandler> xDocBuilder( + mxServiceFactory->createInstance(::rtl::OUString::createFromAscii( + "com.sun.star.xml.dom.SAXDocumentBuilder")), + uno::UNO_QUERY_THROW); + return new SvXMLMetaDocumentContext( + *this, nPrefix, rLocalName, mxDocProps, xDocBuilder); + } + else + { + return SvXMLImport::CreateContext(nPrefix, rLocalName, xAttrList); + } +} + +void SAL_CALL XMLMetaImportComponent::setTargetDocument( + const uno::Reference< lang::XComponent >& xDoc ) + throw(lang::IllegalArgumentException, uno::RuntimeException) +{ + mxDocProps = uno::Reference< document::XDocumentProperties >::query( xDoc ); + if( !mxDocProps.is() ) + throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( + "XMLMetaImportComponent::setTargetDocument: argument is no " + "XDocumentProperties"), uno::Reference<uno::XInterface>(*this), 0); +} + +uno::Sequence< rtl::OUString > SAL_CALL + XMLMetaImportComponent_getSupportedServiceNames() + throw() +{ + const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.document.XMLOasisMetaImporter" ) ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +rtl::OUString SAL_CALL XMLMetaImportComponent_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLMetaImportComponent" ) ); +} + +uno::Reference< uno::XInterface > SAL_CALL XMLMetaImportComponent_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr) + throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new XMLMetaImportComponent; + return (cppu::OWeakObject*)new XMLMetaImportComponent(rSMgr); +} + diff --git a/xmloff/source/meta/makefile.mk b/xmloff/source/meta/makefile.mk new file mode 100644 index 000000000000..5efb538c9856 --- /dev/null +++ b/xmloff/source/meta/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=xmloff +TARGET=meta +AUTOSEG=true + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/xmlmetae.obj \ + $(SLO)$/xmlmetai.obj \ + $(SLO)$/MetaExportComponent.obj \ + $(SLO)$/MetaImportComponent.obj \ + $(SLO)$/xmlversion.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/xmloff/source/meta/xmlmetae.cxx b/xmloff/source/meta/xmlmetae.cxx new file mode 100644 index 000000000000..8aa0a4054821 --- /dev/null +++ b/xmloff/source/meta/xmlmetae.cxx @@ -0,0 +1,526 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include <tools/debug.hxx> +#include <tools/inetdef.hxx> +#include <i18npool/mslangid.hxx> +#include <tools/urlobj.hxx> +#include <tools/time.hxx> +#include <rtl/ustrbuf.hxx> + +#include <xmloff/xmlmetae.hxx> +#include <xmloff/xmlexp.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/nmspmap.hxx> +#include "xmlnmspe.hxx" + +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/beans/StringPair.hpp> +#include <com/sun/star/xml/dom/XDocument.hpp> +#include <com/sun/star/xml/sax/XSAXSerializable.hpp> + +#include <comphelper/sequenceasvector.hxx> +#include <unotools/docinfohelper.hxx> + +#include <string.h> + + +using namespace com::sun::star; +using namespace ::xmloff::token; + + +//------------------------------------------------------------------------- + +void lcl_AddTwoDigits( rtl::OUStringBuffer& rStr, sal_Int32 nVal ) +{ + if ( nVal < 10 ) + rStr.append( sal_Unicode('0') ); + rStr.append( nVal ); +} + +rtl::OUString +SvXMLMetaExport::GetISODateTimeString( const util::DateTime& rDateTime ) +{ + // return ISO date string "YYYY-MM-DDThh:mm:ss" + + rtl::OUStringBuffer sTmp; + sTmp.append( (sal_Int32) rDateTime.Year ); + sTmp.append( sal_Unicode('-') ); + lcl_AddTwoDigits( sTmp, rDateTime.Month ); + sTmp.append( sal_Unicode('-') ); + lcl_AddTwoDigits( sTmp, rDateTime.Day ); + sTmp.append( sal_Unicode('T') ); + lcl_AddTwoDigits( sTmp, rDateTime.Hours ); + sTmp.append( sal_Unicode(':') ); + lcl_AddTwoDigits( sTmp, rDateTime.Minutes ); + sTmp.append( sal_Unicode(':') ); + lcl_AddTwoDigits( sTmp, rDateTime.Seconds ); + + return sTmp.makeStringAndClear(); +} + +//------------------------------------------------------------------------- + +void SvXMLMetaExport::SimpleStringElement( const rtl::OUString& rText, + sal_uInt16 nNamespace, enum XMLTokenEnum eElementName ) +{ + if ( rText.getLength() ) { + SvXMLElementExport aElem( mrExport, nNamespace, eElementName, + sal_True, sal_False ); + mrExport.Characters( rText ); + } +} + +void SvXMLMetaExport::SimpleDateTimeElement( const util::DateTime & rDate, + sal_uInt16 nNamespace, enum XMLTokenEnum eElementName ) +{ + if (rDate.Month != 0) { // invalid dates are 0-0-0 + rtl::OUString sValue = GetISODateTimeString( rDate ); + if ( sValue.getLength() ) { + SvXMLElementExport aElem( mrExport, nNamespace, eElementName, + sal_True, sal_False ); + mrExport.Characters( sValue ); + } + } +} + +void SvXMLMetaExport::_MExport() +{ + // generator + { + SvXMLElementExport aElem( mrExport, XML_NAMESPACE_META, XML_GENERATOR, + sal_True, sal_True ); + mrExport.Characters( ::utl::DocInfoHelper::GetGeneratorString() ); + } + + // document title + SimpleStringElement ( mxDocProps->getTitle(), + XML_NAMESPACE_DC, XML_TITLE ); + + // description + SimpleStringElement ( mxDocProps->getDescription(), + XML_NAMESPACE_DC, XML_DESCRIPTION ); + + // subject + SimpleStringElement ( mxDocProps->getSubject(), + XML_NAMESPACE_DC, XML_SUBJECT ); + + // created... + SimpleStringElement ( mxDocProps->getAuthor(), + XML_NAMESPACE_META, XML_INITIAL_CREATOR ); + SimpleDateTimeElement( mxDocProps->getCreationDate(), + XML_NAMESPACE_META, XML_CREATION_DATE ); + + // modified... + SimpleStringElement ( mxDocProps->getModifiedBy(), + XML_NAMESPACE_DC, XML_CREATOR ); + SimpleDateTimeElement( mxDocProps->getModificationDate(), + XML_NAMESPACE_DC, XML_DATE ); + + // printed... + SimpleStringElement ( mxDocProps->getPrintedBy(), + XML_NAMESPACE_META, XML_PRINTED_BY ); + SimpleDateTimeElement( mxDocProps->getPrintDate(), + XML_NAMESPACE_META, XML_PRINT_DATE ); + + // keywords + const uno::Sequence< ::rtl::OUString > keywords = mxDocProps->getKeywords(); + for (sal_Int32 i = 0; i < keywords.getLength(); ++i) { + SvXMLElementExport aKwElem( mrExport, XML_NAMESPACE_META, XML_KEYWORD, + sal_True, sal_False ); + mrExport.Characters( keywords[i] ); + } + + // document language + { + const lang::Locale aLocale = mxDocProps->getLanguage(); + ::rtl::OUString sValue = aLocale.Language; + if (sValue.getLength()) { + if ( aLocale.Country.getLength() ) + { + sValue += rtl::OUString::valueOf((sal_Unicode)'-'); + sValue += aLocale.Country; + } + SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DC, XML_LANGUAGE, + sal_True, sal_False ); + mrExport.Characters( sValue ); + } + } + + // editing cycles + { + SvXMLElementExport aElem( mrExport, + XML_NAMESPACE_META, XML_EDITING_CYCLES, + sal_True, sal_False ); + mrExport.Characters( ::rtl::OUString::valueOf( + static_cast<sal_Int32>(mxDocProps->getEditingCycles()) ) ); + } + + // editing duration + // property is a int32 (seconds) + { + sal_Int32 secs = mxDocProps->getEditingDuration(); + SvXMLElementExport aElem( mrExport, + XML_NAMESPACE_META, XML_EDITING_DURATION, + sal_True, sal_False ); + mrExport.Characters( SvXMLUnitConverter::convertTimeDuration( + Time(secs/3600, (secs%3600)/60, secs%60)) ); + } + + // default target + const ::rtl::OUString sDefTarget = mxDocProps->getDefaultTarget(); + if ( sDefTarget.getLength() ) + { + mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, + sDefTarget ); + + //! define strings for xlink:show values + const XMLTokenEnum eShow = + sDefTarget.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("_blank")) + ? XML_NEW : XML_REPLACE; + mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, eShow ); + + SvXMLElementExport aElem( mrExport, + XML_NAMESPACE_META,XML_HYPERLINK_BEHAVIOUR, + sal_True, sal_False ); + } + + // auto-reload + const ::rtl::OUString sReloadURL = mxDocProps->getAutoloadURL(); + const sal_Int32 sReloadDelay = mxDocProps->getAutoloadSecs(); + if (sReloadDelay != 0 || sReloadURL.getLength() != 0) + { + mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, + mrExport.GetRelativeReference( sReloadURL ) ); + + mrExport.AddAttribute( XML_NAMESPACE_META, XML_DELAY, + SvXMLUnitConverter::convertTimeDuration( + Time(sReloadDelay/3600, (sReloadDelay%3600)/60, + sReloadDelay%60 )) ); + + SvXMLElementExport aElem( mrExport, XML_NAMESPACE_META, XML_AUTO_RELOAD, + sal_True, sal_False ); + } + + // template + const rtl::OUString sTplPath = mxDocProps->getTemplateURL(); + if ( sTplPath.getLength() ) + { + mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); + mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST ); + + // template URL + mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, + mrExport.GetRelativeReference(sTplPath) ); + + // template name + mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TITLE, + mxDocProps->getTemplateName() ); + + // template date + mrExport.AddAttribute( XML_NAMESPACE_META, XML_DATE, + GetISODateTimeString( mxDocProps->getTemplateDate() ) ); + + SvXMLElementExport aElem( mrExport, XML_NAMESPACE_META, XML_TEMPLATE, + sal_True, sal_False ); + } + + // user defined fields + uno::Reference< beans::XPropertyAccess > xUserDefined( + mxDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); + const uno::Sequence< beans::PropertyValue > props = + xUserDefined->getPropertyValues(); + for (sal_Int32 i = 0; i < props.getLength(); ++i) { + ::rtl::OUStringBuffer sValueBuffer; + ::rtl::OUStringBuffer sType; + if (!SvXMLUnitConverter::convertAny( + sValueBuffer, sType, props[i].Value)) { + continue; + } + mrExport.AddAttribute( XML_NAMESPACE_META, XML_NAME, props[i].Name ); + mrExport.AddAttribute( XML_NAMESPACE_META, XML_VALUE_TYPE, + sType.makeStringAndClear() ); + SvXMLElementExport aElem( mrExport, XML_NAMESPACE_META, + XML_USER_DEFINED, sal_True, sal_False ); + mrExport.Characters( sValueBuffer.makeStringAndClear() ); + } + + const uno::Sequence< beans::NamedValue > aDocStatistic = + mxDocProps->getDocumentStatistics(); + // write document statistic if there is any provided + if ( aDocStatistic.getLength() ) + { + for ( sal_Int32 nInd = 0; nInd < aDocStatistic.getLength(); nInd++ ) + { + sal_Int32 nValue = 0; + if ( aDocStatistic[nInd].Value >>= nValue ) + { + ::rtl::OUString aValue = rtl::OUString::valueOf( nValue ); + if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "TableCount" ) ) ) ) + mrExport.AddAttribute( + XML_NAMESPACE_META, XML_TABLE_COUNT, aValue ); + else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "ObjectCount" ) ) ) ) + mrExport.AddAttribute( + XML_NAMESPACE_META, XML_OBJECT_COUNT, aValue ); + else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "ImageCount" ) ) ) ) + mrExport.AddAttribute( + XML_NAMESPACE_META, XML_IMAGE_COUNT, aValue ); + else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "PageCount" ) ) ) ) + mrExport.AddAttribute( + XML_NAMESPACE_META, XML_PAGE_COUNT, aValue ); + else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "ParagraphCount" ) ) ) ) + mrExport.AddAttribute( + XML_NAMESPACE_META, XML_PARAGRAPH_COUNT, aValue ); + else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "WordCount" ) ) ) ) + mrExport.AddAttribute( + XML_NAMESPACE_META, XML_WORD_COUNT, aValue ); + else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "CharacterCount" ) ) ) ) + mrExport.AddAttribute( + XML_NAMESPACE_META, XML_CHARACTER_COUNT, aValue ); + else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "CellCount" ) ) ) ) + mrExport.AddAttribute( + XML_NAMESPACE_META, XML_CELL_COUNT, aValue ); + else + { + DBG_ASSERT( sal_False, "Unknown statistic value!\n" ); + } + } + } + SvXMLElementExport aElem( mrExport, + XML_NAMESPACE_META, XML_DOCUMENT_STATISTIC, sal_True, sal_True ); + } +} + +//------------------------------------------------------------------------- + +static const char *s_xmlns = "xmlns"; +static const char *s_xmlns2 = "xmlns:"; +static const char *s_meta = "meta:"; +static const char *s_href = "xlink:href"; + +SvXMLMetaExport::SvXMLMetaExport( + SvXMLExport& i_rExp, + const uno::Reference<document::XDocumentProperties>& i_rDocProps ) : + mrExport( i_rExp ), + mxDocProps( i_rDocProps ), + m_level( 0 ), + m_preservedNSs() +{ + DBG_ASSERT( mxDocProps.is(), "no document properties" ); +} + +SvXMLMetaExport::~SvXMLMetaExport() +{ +} + +void SvXMLMetaExport::Export() +{ +// exportDom(xDOM, mrExport); // this would not work (root node, namespaces) + uno::Reference< xml::sax::XSAXSerializable> xSAXable(mxDocProps, + uno::UNO_QUERY); + if (xSAXable.is()) { + ::comphelper::SequenceAsVector< beans::StringPair > namespaces; + const SvXMLNamespaceMap & rNsMap(mrExport.GetNamespaceMap()); + for (sal_uInt16 key = rNsMap.GetFirstKey(); + key != USHRT_MAX; key = rNsMap.GetNextKey(key)) { + beans::StringPair ns; + const ::rtl::OUString attrname = rNsMap.GetAttrNameByKey(key); + if (attrname.matchAsciiL(s_xmlns2, strlen(s_xmlns2))) { + ns.First = attrname.copy(strlen(s_xmlns2)); + } else if (attrname.equalsAsciiL(s_xmlns, strlen(s_xmlns))) { + // default initialized empty string + } else { + DBG_ERROR("namespace attribute not starting with xmlns unexpected"); + } + ns.Second = rNsMap.GetNameByKey(key); + namespaces.push_back(ns); + } + xSAXable->serialize(this, namespaces.getAsConstList()); + } else { + // office:meta + SvXMLElementExport aElem( mrExport, XML_NAMESPACE_OFFICE, XML_META, + sal_True, sal_True ); + // fall back to using public interface of XDocumentProperties + _MExport(); + } +} + +// ::com::sun::star::xml::sax::XDocumentHandler: +void SAL_CALL +SvXMLMetaExport::startDocument() + throw (uno::RuntimeException, xml::sax::SAXException) +{ + // ignore: has already been done by SvXMLExport::exportDoc + DBG_ASSERT( m_level == 0, "SvXMLMetaExport: level error" ); +} + +void SAL_CALL +SvXMLMetaExport::endDocument() + throw (uno::RuntimeException, xml::sax::SAXException) +{ + // ignore: will be done by SvXMLExport::exportDoc + DBG_ASSERT( m_level == 0, "SvXMLMetaExport: level error" ); +} + +// unfortunately, this method contains far too much ugly namespace mangling. +void SAL_CALL +SvXMLMetaExport::startElement(const ::rtl::OUString & i_rName, + const uno::Reference< xml::sax::XAttributeList > & i_xAttribs) + throw (uno::RuntimeException, xml::sax::SAXException) +{ + + if (m_level == 0) { + // namepace decls: default ones have been written at the root element + // non-default ones must be preserved here + const sal_Int16 nCount = i_xAttribs->getLength(); + for (sal_Int16 i = 0; i < nCount; ++i) { + const ::rtl::OUString name(i_xAttribs->getNameByIndex(i)); + if (name.matchAsciiL(s_xmlns, strlen(s_xmlns))) { + bool found(false); + const SvXMLNamespaceMap & rNsMap(mrExport.GetNamespaceMap()); + for (sal_uInt16 key = rNsMap.GetFirstKey(); + key != USHRT_MAX; key = rNsMap.GetNextKey(key)) { + if (name.equals(rNsMap.GetAttrNameByKey(key))) { + found = true; + break; + } + } + if (!found) { + m_preservedNSs.push_back(beans::StringPair(name, + i_xAttribs->getValueByIndex(i))); + } + } + } + // ignore the root: it has been written already + ++m_level; + return; + } + + if (m_level == 1) { + // attach preserved namespace decls from root node here + for (std::vector<beans::StringPair>::const_iterator iter = + m_preservedNSs.begin(); iter != m_preservedNSs.end(); ++iter) { + const ::rtl::OUString ns(iter->First); + bool found(false); + // but only if it is not already there + const sal_Int16 nCount = i_xAttribs->getLength(); + for (sal_Int16 i = 0; i < nCount; ++i) { + const ::rtl::OUString name(i_xAttribs->getNameByIndex(i)); + if (ns.equals(name)) { + found = true; + break; + } + } + if (!found) { + mrExport.AddAttribute(ns, iter->Second); + } + } + } + + // attach the attributes + if (i_rName.matchAsciiL(s_meta, strlen(s_meta))) { + // special handling for all elements that may have + // xlink:href attributes; these must be made relative + const sal_Int16 nLength = i_xAttribs->getLength(); + for (sal_Int16 i = 0; i < nLength; ++i) { + const ::rtl::OUString name (i_xAttribs->getNameByIndex (i)); + ::rtl::OUString value(i_xAttribs->getValueByIndex(i)); + if (name.matchAsciiL(s_href, strlen(s_href))) { + value = mrExport.GetRelativeReference(value); + } + mrExport.AddAttribute(name, value); + } + } else { + const sal_Int16 nLength = i_xAttribs->getLength(); + for (sal_Int16 i = 0; i < nLength; ++i) { + const ::rtl::OUString name (i_xAttribs->getNameByIndex(i)); + const ::rtl::OUString value (i_xAttribs->getValueByIndex(i)); + mrExport.AddAttribute(name, value); + } + } + + // finally, start the element + mrExport.StartElement(i_rName, sal_True); //FIXME:whitespace? + ++m_level; +} + +void SAL_CALL +SvXMLMetaExport::endElement(const ::rtl::OUString & i_rName) + throw (uno::RuntimeException, xml::sax::SAXException) +{ + --m_level; + if (m_level == 0) { + // ignore the root; see startElement + return; + } + DBG_ASSERT( m_level >= 0, "SvXMLMetaExport: level error" ); + mrExport.EndElement(i_rName, sal_False); +} + +void SAL_CALL +SvXMLMetaExport::characters(const ::rtl::OUString & i_rChars) + throw (uno::RuntimeException, xml::sax::SAXException) +{ + mrExport.Characters(i_rChars); +} + +void SAL_CALL +SvXMLMetaExport::ignorableWhitespace(const ::rtl::OUString & /*i_rWhitespaces*/) + throw (uno::RuntimeException, xml::sax::SAXException) +{ + mrExport.IgnorableWhitespace(/*i_rWhitespaces*/); +} + +void SAL_CALL +SvXMLMetaExport::processingInstruction(const ::rtl::OUString & i_rTarget, + const ::rtl::OUString & i_rData) + throw (uno::RuntimeException, xml::sax::SAXException) +{ + // ignore; the exporter cannot handle these + (void) i_rTarget; + (void) i_rData; +} + +void SAL_CALL +SvXMLMetaExport::setDocumentLocator(const uno::Reference<xml::sax::XLocator>&) + throw (uno::RuntimeException, xml::sax::SAXException) +{ + // nothing to do here, move along... +} + + diff --git a/xmloff/source/meta/xmlmetai.cxx b/xmloff/source/meta/xmlmetai.cxx new file mode 100644 index 000000000000..35dab510210a --- /dev/null +++ b/xmloff/source/meta/xmlmetai.cxx @@ -0,0 +1,277 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/xml/dom/XSAXDocumentBuilder.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> + +#include <tools/debug.hxx> + +#include <xmloff/xmlmetai.hxx> +#include <xmloff/xmlimp.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include "xmlnmspe.hxx" + + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using namespace com::sun::star; +using namespace ::xmloff::token; + + +//=========================================================================== + +/// builds a DOM tree from SAX events, by forwarding to SAXDocumentBuilder +class XMLDocumentBuilderContext : public SvXMLImportContext +{ +private: + ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XDocumentHandler> mxDocBuilder; + +public: + XMLDocumentBuilderContext(SvXMLImport& rImport, USHORT nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XDocumentHandler>& rDocBuilder); + + virtual ~XMLDocumentBuilderContext(); + + virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix, + const rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void StartElement( const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList >& xAttrList ); + + virtual void Characters( const ::rtl::OUString& rChars ); + + virtual void EndElement(); +}; + +XMLDocumentBuilderContext::XMLDocumentBuilderContext(SvXMLImport& rImport, + USHORT nPrfx, const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>&, + const uno::Reference<xml::sax::XDocumentHandler>& rDocBuilder) : + SvXMLImportContext( rImport, nPrfx, rLName ), + mxDocBuilder(rDocBuilder) +{ +} + +XMLDocumentBuilderContext::~XMLDocumentBuilderContext() +{ +} + +SvXMLImportContext * +XMLDocumentBuilderContext::CreateChildContext( USHORT nPrefix, + const rtl::OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList>& rAttrs) +{ + return new XMLDocumentBuilderContext( + GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder); +} + +void XMLDocumentBuilderContext::StartElement( + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) +{ + mxDocBuilder->startElement( + GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()), + xAttrList); +} + +void XMLDocumentBuilderContext::Characters( const ::rtl::OUString& rChars ) +{ + mxDocBuilder->characters(rChars); +} + +void XMLDocumentBuilderContext::EndElement() +{ + mxDocBuilder->endElement( + GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName())); +} + + +//=========================================================================== + +SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport& rImport, + USHORT nPrfx, const rtl::OUString& rLName, + const uno::Reference<document::XDocumentProperties>& xDocProps, + const uno::Reference<xml::sax::XDocumentHandler>& xDocBuilder) : + SvXMLImportContext( rImport, nPrfx, rLName ), + mxDocProps(xDocProps), + mxDocBuilder(xDocBuilder) +{ + DBG_ASSERT(xDocProps.is(), "SvXMLMetaDocumentContext: no document props"); + DBG_ASSERT(xDocBuilder.is(), "SvXMLMetaDocumentContext: no document hdlr"); + // here are no attributes +} + +SvXMLMetaDocumentContext::~SvXMLMetaDocumentContext() +{ +} + +SvXMLImportContext *SvXMLMetaDocumentContext::CreateChildContext( + USHORT nPrefix, const rtl::OUString& rLocalName, + const uno::Reference<xml::sax::XAttributeList>& rAttrs) +{ + if ( (XML_NAMESPACE_OFFICE == nPrefix) && + IsXMLToken(rLocalName, XML_META) ) + { + return new XMLDocumentBuilderContext( + GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder); + } + else + { + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + } +} + + +void SvXMLMetaDocumentContext::StartElement( + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) +{ + mxDocBuilder->startDocument(); + // hardcode office:document-meta (necessary in case of flat file ODF) + mxDocBuilder->startElement( + GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), + GetXMLToken(XML_DOCUMENT_META)), xAttrList); +} + +void SvXMLMetaDocumentContext::EndElement() +{ + // hardcode office:document-meta (necessary in case of flat file ODF) + mxDocBuilder->endElement( + GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), + GetXMLToken(XML_DOCUMENT_META))); + mxDocBuilder->endDocument(); + initDocumentProperties(); +} + +void SvXMLMetaDocumentContext::initDocumentProperties() +{ + uno::Sequence< uno::Any > aSeq(1); + uno::Reference< xml::dom::XSAXDocumentBuilder > xDB (mxDocBuilder, + uno::UNO_QUERY_THROW); + aSeq[0] <<= xDB->getDocument(); + uno::Reference< lang::XInitialization > xInit(mxDocProps, + uno::UNO_QUERY_THROW); + try { + xInit->initialize(aSeq); + GetImport().SetStatistics(mxDocProps->getDocumentStatistics()); + // convert all URLs from relative to absolute + mxDocProps->setTemplateURL(GetImport().GetAbsoluteReference( + mxDocProps->getTemplateURL())); + mxDocProps->setAutoloadURL(GetImport().GetAbsoluteReference( + mxDocProps->getAutoloadURL())); + setBuildId(mxDocProps->getGenerator()); + } catch (uno::RuntimeException) { + throw; + } catch (uno::Exception & e) { + throw lang::WrappedTargetRuntimeException( + ::rtl::OUString::createFromAscii( + "SvXMLMetaDocumentContext::initDocumentProperties: " + "properties init exception"), + GetImport(), makeAny(e)); + } +} + +void SvXMLMetaDocumentContext::setBuildId(const ::rtl::OUString & i_rBuildId) +{ + SvXMLMetaDocumentContext::setBuildId( i_rBuildId, GetImport().getImportInfo() ); +} + +//static +void SvXMLMetaDocumentContext::setBuildId(::rtl::OUString const& i_rBuildId, const uno::Reference<beans::XPropertySet>& xImportInfo ) +{ + OUString sBuildId; + // skip to second product + sal_Int32 nBegin = i_rBuildId.indexOf( ' ' ); + if ( nBegin != -1 ) + { + // skip to build information + nBegin = i_rBuildId.indexOf( '/', nBegin ); + if ( nBegin != -1 ) + { + sal_Int32 nEnd = i_rBuildId.indexOf( 'm', nBegin ); + if ( nEnd != -1 ) + { + OUStringBuffer sBuffer( + i_rBuildId.copy( nBegin+1, nEnd-nBegin-1 ) ); + const OUString sBuildCompare( + RTL_CONSTASCII_USTRINGPARAM( "$Build-" ) ); + nBegin = i_rBuildId.indexOf( sBuildCompare, nEnd ); + if ( nBegin != -1 ) + { + sBuffer.append( (sal_Unicode)'$' ); + sBuffer.append( i_rBuildId.copy( + nBegin + sBuildCompare.getLength() ) ); + sBuildId = sBuffer.makeStringAndClear(); + } + } + } + } + + if ( sBuildId.getLength() == 0 ) + { + if ((i_rBuildId.compareToAscii( + RTL_CONSTASCII_STRINGPARAM("StarOffice 7") ) == 0) || + (i_rBuildId.compareToAscii( + RTL_CONSTASCII_STRINGPARAM("StarSuite 7") ) == 0) || + (i_rBuildId.compareToAscii( + RTL_CONSTASCII_STRINGPARAM("OpenOffice.org 1") ) == 0)) + { + sBuildId = OUString::createFromAscii( "645$8687" ); + } + if ((i_rBuildId.compareToAscii( RTL_CONSTASCII_STRINGPARAM("NeoOffice/2") ) == 0) ) + { + sBuildId = OUString::createFromAscii( "680$9134" ); // fake NeoOffice as OpenOffice.org 2.2 release + } + } + + if ( sBuildId.getLength() ) try + { + if( xImportInfo.is() ) + { + const OUString aPropName(RTL_CONSTASCII_USTRINGPARAM("BuildId")); + uno::Reference< beans::XPropertySetInfo > xSetInfo( + xImportInfo->getPropertySetInfo()); + if( xSetInfo.is() && xSetInfo->hasPropertyByName( aPropName ) ) + xImportInfo->setPropertyValue( aPropName, uno::makeAny( sBuildId ) ); + } + } + catch( uno::Exception& ) + { + } +} + diff --git a/xmloff/source/meta/xmlversion.cxx b/xmloff/source/meta/xmlversion.cxx new file mode 100644 index 000000000000..819fa13500e1 --- /dev/null +++ b/xmloff/source/meta/xmlversion.cxx @@ -0,0 +1,541 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" +#include <com/sun/star/embed/ElementModes.hpp> +#include <tools/debug.hxx> +#include <unotools/streamwrap.hxx> +#include <xmlversion.hxx> +#include <xmloff/xmlmetae.hxx> + +#include <xmloff/xmltoken.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/xml/sax/InputSource.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> + +#include <tools/string.hxx> +class SvStringsDtor; + +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; +using ::rtl::OUString; + +// ------------------------------------------------------------------------ + +sal_Char __FAR_DATA XMLN_VERSIONSLIST[] = "VersionList.xml"; + +// ------------------------------------------------------------------------ + +// #110897# +XMLVersionListExport::XMLVersionListExport( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory, + const com::sun::star::uno::Sequence < com::sun::star::util::RevisionTag >& rVersions, + const OUString &rFileName, + Reference< XDocumentHandler > &rHandler ) +: SvXMLExport( xServiceFactory, rFileName, rHandler ), + maVersions( rVersions ) +{ + _GetNamespaceMap().AddAtIndex( XML_NAMESPACE_DC_IDX, xmloff::token::GetXMLToken(xmloff::token::XML_NP_DC), + xmloff::token::GetXMLToken(xmloff::token::XML_N_DC), XML_NAMESPACE_DC ); + _GetNamespaceMap().AddAtIndex( XML_NAMESPACE_FRAMEWORK_IDX, xmloff::token::GetXMLToken(xmloff::token::XML_NP_VERSIONS_LIST), + xmloff::token::GetXMLToken(xmloff::token::XML_N_VERSIONS_LIST), XML_NAMESPACE_FRAMEWORK ); +} + +// ------------------------------------------------------------------------ +sal_uInt32 XMLVersionListExport::exportDoc( enum ::xmloff::token::XMLTokenEnum ) +{ + GetDocHandler()->startDocument(); + + sal_uInt16 nPos = _GetNamespaceMap().GetIndexByKey( XML_NAMESPACE_DC ); + + AddAttribute( XML_NAMESPACE_NONE, _GetNamespaceMap().GetAttrNameByIndex( nPos ), + _GetNamespaceMap().GetNameByIndex ( nPos ) ); + + nPos = _GetNamespaceMap().GetIndexByKey( XML_NAMESPACE_FRAMEWORK ); + AddAttribute( XML_NAMESPACE_NONE, _GetNamespaceMap().GetAttrNameByIndex( nPos ), + _GetNamespaceMap().GetNameByIndex ( nPos ) ); + + { + // the following object will write all collected attributes in its dtor + SvXMLElementExport aRoot( *this, XML_NAMESPACE_FRAMEWORK, xmloff::token::XML_VERSION_LIST, sal_True, sal_True ); + + for ( sal_Int32 n=0; n<maVersions.getLength(); n++ ) + { + const util::RevisionTag& rInfo = maVersions[n]; + AddAttribute( XML_NAMESPACE_FRAMEWORK, + xmloff::token::XML_TITLE, + OUString( rInfo.Identifier ) ); + AddAttribute( XML_NAMESPACE_FRAMEWORK, + xmloff::token::XML_COMMENT, + OUString( rInfo.Comment ) ); + AddAttribute( XML_NAMESPACE_FRAMEWORK, + xmloff::token::XML_CREATOR, + OUString( rInfo.Author ) ); + + OUString aDateStr = + SvXMLMetaExport::GetISODateTimeString( rInfo.TimeStamp ); + + AddAttribute( XML_NAMESPACE_DC, xmloff::token::XML_DATE_TIME, aDateStr ); + + // the following object will write all collected attributes in its dtor + SvXMLElementExport aEntry( *this, XML_NAMESPACE_FRAMEWORK, xmloff::token::XML_VERSION_ENTRY, sal_True, sal_True ); + } + } + GetDocHandler()->endDocument(); + return 0; +} + +// ------------------------------------------------------------------------ +// ------------------------------------------------------------------------ + +// #110897# +XMLVersionListImport::XMLVersionListImport( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory, + com::sun::star::uno::Sequence < com::sun::star::util::RevisionTag >& rVersions ) +: SvXMLImport(xServiceFactory), + maVersions( rVersions ) +{ + GetNamespaceMap().AddAtIndex( XML_NAMESPACE_FRAMEWORK_IDX, xmloff::token::GetXMLToken(xmloff::token::XML_NP_VERSIONS_LIST), + xmloff::token::GetXMLToken(xmloff::token::XML_N_VERSIONS_LIST), XML_NAMESPACE_FRAMEWORK ); +} + +// ------------------------------------------------------------------------ +XMLVersionListImport::~XMLVersionListImport( void ) throw() +{} + +// ------------------------------------------------------------------------ +SvXMLImportContext *XMLVersionListImport::CreateContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference< XAttributeList > & xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if ( XML_NAMESPACE_FRAMEWORK == nPrefix && + rLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_VERSION_LIST) ) + { + pContext = new XMLVersionListContext( *this, nPrefix, rLocalName, xAttrList ); + } + else + { + pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList ); + } + + return pContext; +} + + +// ------------------------------------------------------------------------ +// ------------------------------------------------------------------------ + +XMLVersionListContext::XMLVersionListContext( XMLVersionListImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference< XAttributeList > & ) + : SvXMLImportContext( rImport, nPrefix, rLocalName ) + , rLocalRef( rImport ) +{ +} + +// ------------------------------------------------------------------------ +XMLVersionListContext::~XMLVersionListContext( void ) +{} + +// ------------------------------------------------------------------------ +SvXMLImportContext *XMLVersionListContext::CreateChildContext( sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference< XAttributeList > & xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if ( nPrefix == XML_NAMESPACE_FRAMEWORK && + rLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_VERSION_ENTRY) ) + { + pContext = new XMLVersionContext( rLocalRef, nPrefix, rLocalName, xAttrList ); + } + else + { + pContext = new SvXMLImportContext( rLocalRef, nPrefix, rLocalName ); + } + + return pContext; +} + +// ------------------------------------------------------------------------ +// ------------------------------------------------------------------------ + +XMLVersionContext::XMLVersionContext( XMLVersionListImport& rImport, + sal_uInt16 nPref, + const OUString& rLocalName, + const Reference< XAttributeList > & xAttrList ) + : SvXMLImportContext( rImport, nPref, rLocalName ) + , rLocalRef( rImport ) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + + if ( !nAttrCount ) + return; + + util::RevisionTag aInfo; + for ( sal_Int16 i=0; i < nAttrCount; i++ ) + { + OUString aLocalName; + const OUString& rAttrName = xAttrList->getNameByIndex( i ); + sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ); + + if ( XML_NAMESPACE_FRAMEWORK == nPrefix ) + { + if ( aLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_TITLE) ) + { + const OUString& rAttrValue = xAttrList->getValueByIndex( i ); + aInfo.Identifier = rAttrValue; + } + else if ( aLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_COMMENT) ) + { + const OUString& rAttrValue = xAttrList->getValueByIndex( i ); + aInfo.Comment = rAttrValue; + } + else if ( aLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_CREATOR) ) + { + const OUString& rAttrValue = xAttrList->getValueByIndex( i ); + aInfo.Author = rAttrValue; + } + } + else if ( ( XML_NAMESPACE_DC == nPrefix ) && + ( aLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_DATE_TIME) ) ) + { + const OUString& rAttrValue = xAttrList->getValueByIndex( i ); + util::DateTime aTime; + if ( ParseISODateTimeString( rAttrValue, aTime ) ) + aInfo.TimeStamp = aTime; + } + } + + uno::Sequence < util::RevisionTag >& aList = rLocalRef.GetList(); + sal_Int32 nLength = aList.getLength(); + aList.realloc( nLength+1 ); + aList[nLength] = aInfo; +} + + +// ------------------------------------------------------------------------ +XMLVersionContext::~XMLVersionContext( void ) +{} + +// ------------------------------------------------------------------------ +// static +sal_Bool XMLVersionContext::ParseISODateTimeString( + const rtl::OUString& rString, + util::DateTime& rDateTime ) +{ + sal_Bool bSuccess = sal_True; + + OUString aDateStr, aTimeStr; + sal_Int32 nPos = rString.indexOf( (sal_Unicode) 'T' ); + if ( nPos >= 0 ) + { + aDateStr = rString.copy( 0, nPos ); + aTimeStr = rString.copy( nPos + 1 ); + } + else + aDateStr = rString; // no separator: only date part + + sal_Int32 nYear = 0; + sal_Int32 nMonth = 1; + sal_Int32 nDay = 1; + sal_Int32 nHour = 0; + sal_Int32 nMin = 0; + sal_Int32 nSec = 0; + + const sal_Unicode* pStr = aDateStr.getStr(); + sal_Int32 nDateTokens = 1; + while ( *pStr ) + { + if ( *pStr == '-' ) + nDateTokens++; + pStr++; + } + if ( nDateTokens > 3 || aDateStr.getLength() == 0 ) + bSuccess = sal_False; + else + { + sal_Int32 n = 0; + nYear = aDateStr.getToken( 0, '-', n ).toInt32(); + if ( nYear > 9999 ) + bSuccess = sal_False; + else if ( nDateTokens >= 2 ) + { + nMonth = aDateStr.getToken( 0, '-', n ).toInt32(); + if ( nMonth > 12 ) + bSuccess = sal_False; + else if ( nDateTokens >= 3 ) + { + nDay = aDateStr.getToken( 0, '-', n ).toInt32(); + if ( nDay > 31 ) + bSuccess = sal_False; + } + } + } + + if ( bSuccess && aTimeStr.getLength() > 0 ) // time is optional + { + pStr = aTimeStr.getStr(); + sal_Int32 nTimeTokens = 1; + while ( *pStr ) + { + if ( *pStr == ':' ) + nTimeTokens++; + pStr++; + } + if ( nTimeTokens > 3 ) + bSuccess = sal_False; + else + { + sal_Int32 n = 0; + nHour = aTimeStr.getToken( 0, ':', n ).toInt32(); + if ( nHour > 23 ) + bSuccess = sal_False; + else if ( nTimeTokens >= 2 ) + { + nMin = aTimeStr.getToken( 0, ':', n ).toInt32(); + if ( nMin > 59 ) + bSuccess = sal_False; + else if ( nTimeTokens >= 3 ) + { + nSec = aTimeStr.getToken( 0, ':', n ).toInt32(); + if ( nSec > 59 ) + bSuccess = sal_False; + } + } + } + } + + if ( bSuccess ) + { + rDateTime.Day = sal::static_int_cast< sal_uInt16 >(nDay); + rDateTime.Month = sal::static_int_cast< sal_uInt16 >(nMonth); + rDateTime.Year = sal::static_int_cast< sal_uInt16 >(nYear); + rDateTime.Hours = sal::static_int_cast< sal_uInt16 >(nHour); + rDateTime.Minutes = sal::static_int_cast< sal_uInt16 >(nMin); + rDateTime.Seconds = sal::static_int_cast< sal_uInt16 >(nSec); + } + + return bSuccess; +} + + +// ------------------------------------------------------------------------ +// ------------------------------------------------------------------------ + +void SAL_CALL XMLVersionListPersistence::store( const uno::Reference< embed::XStorage >& xRoot, const uno::Sequence< util::RevisionTag >& rVersions ) + throw (::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + // no storage, no version list! + if ( xRoot.is() ) + { + // get the services needed for writing the xml data + Reference< lang::XMultiServiceFactory > xServiceFactory = + comphelper::getProcessServiceFactory(); + DBG_ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" ); + + Reference< XInterface > xWriter (xServiceFactory->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer")))); + DBG_ASSERT( xWriter.is(), "com.sun.star.xml.sax.Writer service missing" ); + + // check wether there's already a sub storage with the version info + // and delete it + OUString sVerName( RTL_CONSTASCII_USTRINGPARAM( XMLN_VERSIONSLIST ) ); + + // is this really needed, we set the size to zero before doing + // anything with this stream? +/* if ( xRoot->IsContained( sVerName ) ) + { + xRoot->Remove( sVerName ); + xRoot->Commit(); + } +*/ + try { + // open (create) the sub storage with the version info + uno::Reference< io::XStream > xVerStream = xRoot->openStreamElement( + sVerName, + embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); + if ( !xVerStream.is() ) + throw uno::RuntimeException(); + +//REMOVE // SetSize should not be neccessary because OpenStream( WRITE|TRUNC ) should already +//REMOVE // have set the size to zero +//REMOVE // xVerStream->SetSize ( 0L ); +//REMOVE xVerStream->SetBufferSize( 16*1024 ); + + Reference< io::XOutputStream > xOut = xVerStream->getOutputStream(); + if ( !xOut.is() ) + throw uno::RuntimeException(); // the stream was successfuly opened for writing already + + Reference< io::XActiveDataSource > xSrc( xWriter, uno::UNO_QUERY ); + xSrc->setOutputStream(xOut); + + Reference< XDocumentHandler > xHandler( xWriter, uno::UNO_QUERY ); + + // XMLVersionListExport aExp( pList, sVerName, xHandler ); + XMLVersionListExport aExp( xServiceFactory, rVersions, sVerName, xHandler ); + + aExp.exportDoc( ::xmloff::token::XML_VERSION ); + +//REMOVE xVerStream->Commit(); + xVerStream = uno::Reference< io::XStream >(); // use refcounting for now to dispose + // xRoot->Commit(); + } + catch( uno::Exception& ) + { + // TODO: error handling + } + } +} + +// ------------------------------------------------------------------------ +uno::Sequence< util::RevisionTag > SAL_CALL XMLVersionListPersistence::load( const uno::Reference< embed::XStorage >& xRoot ) + throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + com::sun::star::uno::Sequence < com::sun::star::util::RevisionTag > aVersions; + + const OUString sDocName( RTL_CONSTASCII_USTRINGPARAM( XMLN_VERSIONSLIST ) ); + uno::Reference< container::XNameAccess > xRootNames( xRoot, uno::UNO_QUERY ); + + try { + if ( xRootNames.is() && xRootNames->hasByName( sDocName ) && xRoot->isStreamElement( sDocName ) ) + { + Reference< lang::XMultiServiceFactory > xServiceFactory = + comphelper::getProcessServiceFactory(); + DBG_ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" ); + + InputSource aParserInput; + + uno::Reference< beans::XPropertySet > xProps( xRoot, uno::UNO_QUERY ); + OSL_ENSURE( xProps.is(), "Storage must implement XPropertySet!\n" ); + if ( xProps.is() ) + { + try { + xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "URL" ) ) >>= aParserInput.sSystemId; + } + catch( uno::Exception& ) + {} + } + + uno::Reference< io::XStream > xDocStream = xRoot->openStreamElement( + sDocName, + embed::ElementModes::READ ); + if ( !xDocStream.is() ) + throw uno::RuntimeException(); + +//REMOVE xDocStream->Seek( 0L ); +//REMOVE xDocStream->SetBufferSize( 16*1024 ); + + aParserInput.aInputStream = xDocStream->getInputStream(); + OSL_ENSURE( aParserInput.aInputStream.is(), + "The stream was successfuly opened for reading, the input part must be accessible!\n" ); + if ( !aParserInput.aInputStream.is() ) + throw uno::RuntimeException(); + + // get parser + Reference< XInterface > xXMLParser = xServiceFactory->createInstance( + OUString::createFromAscii("com.sun.star.xml.sax.Parser") ); + DBG_ASSERT( xXMLParser.is(), + "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" ); + + // get filter + // Reference< XDocumentHandler > xFilter = new XMLVersionListImport( pList ); + Reference< XDocumentHandler > xFilter = new XMLVersionListImport( xServiceFactory, aVersions ); + + // connect parser and filter + Reference< XParser > xParser( xXMLParser, UNO_QUERY ); + xParser->setDocumentHandler( xFilter ); + + // parse + try + { + xParser->parseStream( aParserInput ); + } + catch( SAXParseException& ) {} + catch( SAXException& ) {} + catch( io::IOException& ) {} + } + } + catch( uno::Exception& ) + { + // TODO: error handling + } + + return aVersions; +} + +uno::Sequence< rtl::OUString > SAL_CALL XMLVersionListPersistence_getSupportedServiceNames() + throw() +{ + const rtl::OUString aServiceName( + RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.DocumentRevisionListPersistence" ) ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +rtl::OUString SAL_CALL XMLVersionListPersistence_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLVersionListPersistence" ) ); +} + +uno::Reference< uno::XInterface > SAL_CALL XMLVersionListPersistence_createInstance( + const uno::Reference< lang::XMultiServiceFactory > &) + throw( uno::Exception ) +{ + return (cppu::OWeakObject*)new XMLVersionListPersistence; +} + +uno::Sequence< rtl::OUString > SAL_CALL XMLVersionImExportOOO_getSupportedServiceNames() + throw() +{ + const rtl::OUString aServiceName( + RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.DocumentRevisionListPersistence" ) ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +rtl::OUString SAL_CALL XMLVersionImExportOOO_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLVersionImExportOOo" ) ); +} + +uno::Reference< uno::XInterface > SAL_CALL XMLVersionImExportOOO_createInstance( + const uno::Reference< lang::XMultiServiceFactory > &) + throw( uno::Exception ) +{ + return (cppu::OWeakObject*)new XMLVersionListPersistence; +} + |