Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  xmlversion.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <com/sun/star/embed/ElementModes.hpp>
#include <xmlversion.hxx>
#include <xmloff/xmlnamespace.hxx>
#include <xmloff/xmlmetae.hxx>
#include <osl/diagnose.h>
#include <sal/log.hxx>
#include <o3tl/string_view.hxx>

#include <xmloff/xmltoken.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/io/IOException.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/util/MeasureUnit.hpp>
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/xml/sax/Writer.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <cppuhelper/supportsservice.hxx>

using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;

constexpr OUString XMLN_VERSIONSLIST = u"VersionList.xml"_ustr;

XMLVersionListExport::XMLVersionListExport(
    const css::uno::Reference< css::uno::XComponentContext >& rContext,
    const css::uno::Sequence < css::util::RevisionTag >& rVersions,
    const OUString &rFileName,
    Reference< XDocumentHandler > const &rHandler )
:   SvXMLExport( rContext, u""_ustr, rFileName, util::MeasureUnit::CM, rHandler ),
    maVersions( rVersions )
{
    GetNamespaceMap_().AddAtIndex( xmloff::token::GetXMLToken(xmloff::token::XML_NP_DC),
                                   xmloff::token::GetXMLToken(xmloff::token::XML_N_DC), XML_NAMESPACE_DC );
    GetNamespaceMap_().AddAtIndex( xmloff::token::GetXMLToken(xmloff::token::XML_NP_VERSIONS_LIST),
                                   xmloff::token::GetXMLToken(xmloff::token::XML_N_VERSIONS_LIST), XML_NAMESPACE_FRAMEWORK );
}

ErrCode XMLVersionListExport::exportDoc( enum ::xmloff::token::XMLTokenEnum )
{
    GetDocHandler()->startDocument();

    addChaffWhenEncryptedStorage();

    sal_uInt16 nPos = SvXMLNamespaceMap::GetIndexByKey( XML_NAMESPACE_DC );

    AddAttribute( GetNamespaceMap_().GetAttrNameByIndex( nPos ),
                             GetNamespaceMap_().GetNameByIndex ( nPos ) );

    nPos = SvXMLNamespaceMap::GetIndexByKey( XML_NAMESPACE_FRAMEWORK );
    AddAttribute( 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, truetrue );

        for ( const util::RevisionTag& rInfo : maVersions )
        {
            AddAttribute( XML_NAMESPACE_FRAMEWORK,
                          xmloff::token::XML_TITLE,
                          rInfo.Identifier );
            AddAttribute( XML_NAMESPACE_FRAMEWORK,
                          xmloff::token::XML_COMMENT,
                          rInfo.Comment );
            AddAttribute( XML_NAMESPACE_FRAMEWORK,
                          xmloff::token::XML_CREATOR,
                          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, truetrue );
        }
    }
    GetDocHandler()->endDocument();
    return ERRCODE_NONE;
}

XMLVersionListImport::XMLVersionListImport(
    const css::uno::Reference< css::uno::XComponentContext >& rContext,
    css::uno::Sequence < css::util::RevisionTag >& rVersions )
:   SvXMLImport(rContext, u""_ustr),
    maVersions( rVersions )
{
}

XMLVersionListImport::~XMLVersionListImport() noexcept
{}

SvXMLImportContext *XMLVersionListImport::CreateFastContext( sal_Int32 nElement,
        const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
    SvXMLImportContext *pContext = nullptr;

    if ( nElement == XML_ELEMENT(VERSIONS_LIST, xmloff::token::XML_VERSION_LIST) )
    {
        pContext = new XMLVersionListContext( *this );
    }

    return pContext;
}

XMLVersionListContext::XMLVersionListContext( XMLVersionListImport& rImport)
    : SvXMLImportContext( rImport )
{
}

XMLVersionListContext::~XMLVersionListContext()
{}

css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
XMLVersionListContext::createFastChildContext(sal_Int32 nElement,
            const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList)
{
    SvXMLImportContext *pContext = nullptr;

    if ( nElement == XML_ELEMENT(FRAMEWORK, xmloff::token::XML_VERSION_ENTRY)
        || nElement == XML_ELEMENT(VERSIONS_LIST, xmloff::token::XML_VERSION_ENTRY) )
    {
        pContext = new XMLVersionContext( GetImport(), xAttrList );
    }

    return pContext;
}

XMLVersionContext::XMLVersionContext( XMLVersionListImport& rImport,
                                        const Reference< XFastAttributeList > & xAttrList )
    : SvXMLImportContext( rImport )
{
    sax_fastparser::FastAttributeList& rAttribList =
        sax_fastparser::castToFastAttributeList( xAttrList );
    if ( rAttribList.getFastAttributeTokens().empty() )
        return;
    util::RevisionTag aInfo;
    for (auto &aIter : rAttribList)
    {
        switch( aIter.getToken() )
        {
        case XML_ELEMENT(FRAMEWORK, xmloff::token::XML_TITLE):
        case XML_ELEMENT(VERSIONS_LIST, xmloff::token::XML_TITLE):
        {
            aInfo.Identifier = aIter.toString();
            break;
        }
        case XML_ELEMENT(FRAMEWORK, xmloff::token::XML_COMMENT):
        case XML_ELEMENT(VERSIONS_LIST, xmloff::token::XML_COMMENT):
        {
            aInfo.Comment = aIter.toString();
            break;
        }
        case XML_ELEMENT(FRAMEWORK, xmloff::token::XML_CREATOR):
        case XML_ELEMENT(VERSIONS_LIST, xmloff::token::XML_CREATOR):
        {
            aInfo.Author = aIter.toString();
            break;
        }
        case XML_ELEMENT(DC, xmloff::token::XML_DATE_TIME):
        {
            util::DateTime aTime;
            if ( ParseISODateTimeString( aIter.toString(), aTime ) )
                aInfo.TimeStamp = aTime;
            break;
        }
        default:
            XMLOFF_WARN_UNKNOWN("xmloff", aIter);
            break;
        }
    }

    uno::Sequence < util::RevisionTag >& aList = rImport.GetList();
    sal_Int32 nLength = aList.getLength();
    aList.realloc( nLength+1 );
    aList.getArray()[nLength] = std::move(aInfo);
}

XMLVersionContext::~XMLVersionContext()
{}

bool XMLVersionContext::ParseISODateTimeString(
                                std::u16string_view rString,
                                util::DateTime& rDateTime )
{
    bool bSuccess = true;

    std::u16string_view aDateStr, aTimeStr;
    size_t nPos = rString.find( 'T' );
    if ( nPos != std::u16string_view::npos )
    {
        aDateStr = rString.substr( 0, nPos );
        aTimeStr = rString.substr( 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;

    auto pStr = aDateStr.begin();
    sal_Int32 nDateTokens = 1;
    while ( pStr != aDateStr.end() )
    {
        if ( *pStr == '-' )
            nDateTokens++;
        pStr++;
    }
    if ( nDateTokens > 3 || aDateStr.empty() )
        bSuccess = false;
    else
    {
        sal_Int32 n = 0;
        nYear = o3tl::toInt32(o3tl::getToken(aDateStr, 0, '-', n ));
        if ( nYear > 9999 )
            bSuccess = false;
        else if ( nDateTokens >= 2 )
        {
            nMonth = o3tl::toInt32(o3tl::getToken(aDateStr, 0, '-', n ));
            if ( nMonth > 12 )
                bSuccess = false;
            else if ( nDateTokens >= 3 )
            {
                nDay = o3tl::toInt32(o3tl::getToken(aDateStr, 0, '-', n ));
                if ( nDay > 31 )
                    bSuccess = false;
            }
        }
    }

    if ( bSuccess && !aTimeStr.empty() )         // time is optional
    {
        pStr = aTimeStr.begin();
        sal_Int32 nTimeTokens = 1;
        while ( pStr != aTimeStr.end() )
        {
            if ( *pStr == ':' )
                nTimeTokens++;
            pStr++;
        }
        if ( nTimeTokens > 3 )
            bSuccess = false;
        else
        {
            sal_Int32 n = 0;
            nHour = o3tl::toInt32(o3tl::getToken(aTimeStr, 0, ':', n ));
            if ( nHour > 23 )
                bSuccess = false;
            else if ( nTimeTokens >= 2 )
            {
                nMin = o3tl::toInt32(o3tl::getToken(aTimeStr, 0, ':', n ));
                if ( nMin > 59 )
                    bSuccess = false;
                else if ( nTimeTokens >= 3 )
                {
                    nSec = o3tl::toInt32(o3tl::getToken(aTimeStr, 0, ':', n ));
                    if ( nSec > 59 )
                        bSuccess = 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 >&&nbsp;xRoot, const uno::Sequence< util::RevisionTag >& rVersions )
{
    // no storage, no version list!
    if ( !xRoot.is() )
        return;

    // get the services needed for writing the xml data
    const Reference< uno::XComponentContext >& xContext =
            comphelper::getProcessComponentContext();

    Reference< XWriter > xWriter = Writer::create(xContext);

    // check whether there's already a sub storage with the version info
    // and delete it
    OUString sVerName( XMLN_VERSIONSLIST  );

    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();

        Reference< io::XOutputStream > xOut = xVerStream->getOutputStream();
        if ( !xOut.is() )
            throw uno::RuntimeException(u"The stream was successfully opened for writing already!"_ustr);

        xWriter->setOutputStream(xOut);

        rtl::Reference< XMLVersionListExport > xExp( new XMLVersionListExport( xContext, rVersions, sVerName, xWriter ) );

        xExp->exportDoc( ::xmloff::token::XML_VERSION );

        xVerStream.clear(); // use refcounting for now to dispose
    }
    catch( uno::Exception& )
    {
        // TODO: error handling
    }
}

uno::Sequence< util::RevisionTag > SAL_CALL XMLVersionListPersistence::load( const uno::Reference< embed::XStorage >& xRoot )
{
    css::uno::Sequence < css::util::RevisionTag > aVersions;

    const OUString sDocName( XMLN_VERSIONSLIST  );

    try {
        if ( xRoot.is() && xRoot->hasByName( sDocName ) && xRoot->isStreamElement( sDocName ) )
        {
            const Reference< uno::XComponentContext >& xContext = comphelper::getProcessComponentContext();

            InputSource aParserInput;

            uno::Reference< beans::XPropertySet > xProps( xRoot, uno::UNO_QUERY );
            OSL_ENSURE( xProps.is(), "Storage must implement XPropertySet!" );
            if ( xProps.is() )
            {
                try {
                    xProps->getPropertyValue(u"URL"_ustr) >>= aParserInput.sSystemId;
                }
                catch( uno::Exception& )
                {}
            }

            uno::Reference< io::XStream > xDocStream = xRoot->openStreamElement(
                                                            sDocName,
                                                            embed::ElementModes::READ );
            if ( !xDocStream.is() )
                throw uno::RuntimeException();

            aParserInput.aInputStream = xDocStream->getInputStream();
            OSL_ENSURE( aParserInput.aInputStream.is(),
                        "The stream was successfully opened for reading, the input part must be accessible!" );
            if ( !aParserInput.aInputStream.is() )
                throw uno::RuntimeException();

            // get filter
            rtl::Reference< XMLVersionListImport > xImport = new XMLVersionListImport( xContext, aVersions );

            // parse
            try
            {
                xImport->parseStream( aParserInput );
            }
            catch( SAXParseException&  ) {}
            catch( SAXException&  )      {}
            catch( io::IOException& )    {}
        }
    }
    catch( uno::Exception& )
    {
        // TODO: error handling
    }

    return aVersions;
}

OUString XMLVersionListPersistence::getImplementationName()
{
    return u"XMLVersionListPersistence"_ustr;
}

sal_Bool XMLVersionListPersistence::supportsService(
    OUString const & ServiceName)
{
    return cppu::supportsService(this, ServiceName);
}

css::uno::Sequence<OUString>
XMLVersionListPersistence::getSupportedServiceNames()
{
    return css::uno::Sequence<OUString>{
        u"com.sun.star.document.DocumentRevisionListPersistence"_ustr};
}

extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
XMLVersionListPersistence_get_implementation(
    css::uno::XComponentContext *,
    css::uno::Sequence<css::uno::Any> const &)
{
    return cppu::acquire(new XMLVersionListPersistence);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=96 H=95 G=95

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge