VirtualBox

Ignore:
Timestamp:
Mar 6, 2008 10:12:41 AM (17 years ago)
Author:
vboxsync
Message:

Main/Settings: Added XmlTreeBackend::AutoConverter subckasss and old settings tree version memorizing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/xml/Settings.cpp

    r7309 r7315  
    797797{
    798798    Data() : ctxt (NULL), doc (NULL)
    799            , inputResolver (NULL) {}
     799           , inputResolver (NULL)
     800           , autoConverter (NULL), oldVersion (NULL) {}
    800801
    801802    xmlParserCtxtPtr ctxt;
     
    806807    InputResolver *inputResolver;
    807808
     809    AutoConverter *autoConverter;
     810    char *oldVersion;
     811
    808812    std::auto_ptr <stdx::exception_trap_base> trappedErr;
    809 
    810     struct AutoConv
    811     {
    812         AutoConv() : root (NULL), attr (NULL), version (NULL), xslt (NULL) {}
    813         ~AutoConv() { uninit(); }
    814 
    815         void uninit()
    816         {
    817             RTStrFree (xslt); xslt = NULL;
    818             RTStrFree (version); version = NULL;
    819             RTStrFree (attr); attr = NULL;
    820             RTStrFree (root); root = NULL;
    821         }
    822 
    823         bool isNull() { return xslt == NULL; }
    824 
    825         char *root;
    826         char *attr;
    827         char *version;
    828         char *xslt;
    829     }
    830     autoConv;
    831813
    832814    /**
     
    896878}
    897879
    898 void XmlTreeBackend::setAutoConversion (const char *aRoot, const char *aAttr,
    899                                         const char *aVersion, const char *aTemplate)
    900 {
    901     if (aRoot == NULL && aAttr == NULL && aVersion == NULL && aTemplate == NULL)
    902     {
    903         m->autoConv.uninit();
    904         return;
    905     }
    906 
    907     if (aRoot == NULL || aAttr == NULL || aVersion == NULL || aTemplate == NULL)
    908         throw EInvalidArg (RT_SRC_POS);
    909 
    910     m->autoConv.root = RTStrDup (aRoot);
    911     m->autoConv.attr = RTStrDup (aAttr);
    912     m->autoConv.version = RTStrDup (aVersion);
    913     m->autoConv.xslt = RTStrDup (aTemplate);
     880void XmlTreeBackend::setAutoConverter (AutoConverter &aConverter)
     881{
     882    m->autoConverter = &aConverter;
     883}
     884
     885void XmlTreeBackend::resetAutoConverter()
     886{
     887    m->autoConverter = NULL;
     888}
     889
     890const char *XmlTreeBackend::oldVersion() const
     891{
     892    return m->oldVersion;
    914893}
    915894
     
    957936    }
    958937
     938    char *oldVersion = NULL;
     939
    959940    /* perform automatic document transformation if necessary */
    960     if (!m->autoConv.isNull())
     941    if (m->autoConverter != NULL)
    961942    {
    962943        Key root = Key (new XmlKeyBackend (xmlDocGetRootElement (doc)));
    963         if (!strcmp (root.name(), m->autoConv.root))
     944        if (m->autoConverter->needsConversion (root, oldVersion))
    964945        {
    965             const char *ver = root.stringValue (m->autoConv.attr);
    966             if (strcmp (ver, m->autoConv.version))
     946            xmlDocPtr xsltDoc = NULL;
     947            xsltStylesheetPtr xslt = NULL;
     948            xsltTransformContextPtr tranCtxt = NULL;
     949            char *errorStr = NULL;
     950
     951            try
    967952            {
    968                 /* version mismatch */
    969 
    970                 xmlDocPtr xsltDoc = NULL;
    971                 xsltStylesheetPtr xslt = NULL;
    972                 xsltTransformContextPtr tranCtxt = NULL;
    973                 char *errorStr = NULL;
    974 
    975                 try
     953                /* parse the XSLT template */
    976954                {
    977                     /* parse the XSLT */
    978                     {
    979                         Input *xsltInput =
    980                             m->inputResolver->resolveEntity (m->autoConv.xslt, NULL);
    981                         /* NOTE: new InputCtxt instance will be deleted when the
    982                          * stream is closed by the libxml2 API */
    983                         xsltDoc = xmlCtxtReadIO (m->ctxt,
    984                                                  ReadCallback, CloseCallback,
    985                                                  new Data::InputCtxt (xsltInput, m->trappedErr),
    986                                                  m->autoConv.xslt, NULL,
    987                                                  0);
    988                         delete xsltInput;
    989                     }
    990 
    991                     if (xsltDoc == NULL)
    992                     {
    993                         /* look if there was a forwared exception from the lower level */
    994                         if (m->trappedErr.get() != NULL)
    995                             m->trappedErr->rethrow();
    996 
    997                         throw XmlError (xmlCtxtGetLastError (m->ctxt));
    998                     }
    999 
    1000                     xslt = xsltParseStylesheetDoc (xsltDoc);
    1001                     if (xslt == NULL)
    1002                         throw LogicError (RT_SRC_POS);
    1003 
    1004                     /* setup transformation error reporting */
    1005                     tranCtxt = xsltNewTransformContext (xslt, xsltDoc);
    1006                     if (tranCtxt == NULL)
    1007                         throw LogicError (RT_SRC_POS);
    1008                     xsltSetTransformErrorFunc (tranCtxt, &errorStr, ValidityErrorCallback);
    1009 
    1010                     xmlDocPtr newDoc = xsltApplyStylesheetUser (xslt, doc, NULL,
    1011                                                                 NULL, NULL, tranCtxt);
    1012                     if (newDoc == NULL)
    1013                         throw LogicError (RT_SRC_POS);
    1014 
    1015                     if (errorStr != NULL)
    1016                     {
    1017                         xmlFreeDoc (newDoc);
    1018                         throw Error (errorStr);
    1019                         /* errorStr is freed in catch(...) below */
    1020                     }
    1021 
    1022                     /* replace the old document on success */
    1023                     xmlFreeDoc (doc);
    1024                     doc = newDoc;
    1025 
     955                    Input *xsltInput =
     956                        m->inputResolver->resolveEntity
     957                            (m->autoConverter->templateUri(), NULL);
     958                    /* NOTE: new InputCtxt instance will be deleted when the
     959                     * stream is closed by the libxml2 API */
     960                    xsltDoc = xmlCtxtReadIO (m->ctxt,
     961                                             ReadCallback, CloseCallback,
     962                                             new Data::InputCtxt (xsltInput, m->trappedErr),
     963                                             m->autoConverter->templateUri(),
     964                                             NULL, 0);
     965                    delete xsltInput;
     966                }
     967
     968                if (xsltDoc == NULL)
     969                {
     970                    /* look if there was a forwared exception from the lower level */
     971                    if (m->trappedErr.get() != NULL)
     972                        m->trappedErr->rethrow();
     973
     974                    throw XmlError (xmlCtxtGetLastError (m->ctxt));
     975                }
     976
     977                xslt = xsltParseStylesheetDoc (xsltDoc);
     978                if (xslt == NULL)
     979                    throw LogicError (RT_SRC_POS);
     980
     981                /* setup transformation error reporting */
     982                tranCtxt = xsltNewTransformContext (xslt, xsltDoc);
     983                if (tranCtxt == NULL)
     984                    throw LogicError (RT_SRC_POS);
     985                xsltSetTransformErrorFunc (tranCtxt, &errorStr, ValidityErrorCallback);
     986
     987                xmlDocPtr newDoc = xsltApplyStylesheetUser (xslt, doc, NULL,
     988                                                            NULL, NULL, tranCtxt);
     989                if (newDoc == NULL)
     990                    throw LogicError (RT_SRC_POS);
     991
     992                if (errorStr != NULL)
     993                {
     994                    xmlFreeDoc (newDoc);
     995                    throw Error (errorStr);
     996                    /* errorStr is freed in catch(...) below */
     997                }
     998
     999                /* replace the old document on success */
     1000                xmlFreeDoc (doc);
     1001                doc = newDoc;
     1002
     1003                xsltFreeTransformContext (tranCtxt);
     1004
     1005                /* NOTE: xsltFreeStylesheet() also fress the document
     1006                 * passed to xsltParseStylesheetDoc(). */
     1007                xsltFreeStylesheet (xslt);
     1008            }
     1009            catch (...)
     1010            {
     1011                /* restore the previous entity resolver */
     1012                xmlSetExternalEntityLoader (oldEntityLoader);
     1013                sThat = NULL;
     1014
     1015                RTStrFree (errorStr);
     1016
     1017                if (tranCtxt != NULL)
    10261018                    xsltFreeTransformContext (tranCtxt);
    10271019
    1028                     /* NOTE: xsltFreeStylesheet() also fress the document
    1029                      * passed to xsltParseStylesheetDoc(). */
     1020                /* NOTE: xsltFreeStylesheet() also fress the document
     1021                 * passed to xsltParseStylesheetDoc(). */
     1022                if (xslt != NULL)
    10301023                    xsltFreeStylesheet (xslt);
    1031                 }
    1032                 catch (...)
    1033                 {
    1034                     /* restore the previous entity resolver */
    1035                     xmlSetExternalEntityLoader (oldEntityLoader);
    1036                     sThat = NULL;
    1037 
    1038                     RTStrFree (errorStr);
    1039 
    1040                     if (tranCtxt != NULL)
    1041                         xsltFreeTransformContext (tranCtxt);
    1042 
    1043                     /* NOTE: xsltFreeStylesheet() also fress the document
    1044                      * passed to xsltParseStylesheetDoc(). */
    1045                     if (xslt != NULL)
    1046                         xsltFreeStylesheet (xslt);
    1047                     else if (xsltDoc != NULL)
    1048                         xmlFreeDoc (xsltDoc);
    1049 
    1050                     throw;
    1051                 }
     1024                else if (xsltDoc != NULL)
     1025                    xmlFreeDoc (xsltDoc);
     1026
     1027                RTStrFree (oldVersion);
     1028
     1029                throw;
    10521030            }
    10531031        }
     
    11301108                xmlSchemaFreeParserCtxt (schemaCtxt);
    11311109
     1110            RTStrFree (oldVersion);
     1111
    11321112            throw;
    11331113        }
     
    11441124    /* assign the root key */
    11451125    m->root = Key (new XmlKeyBackend (xmlDocGetRootElement (m->doc)));
     1126
     1127    /* memorize the old version string also used as a flag that
     1128     * the conversion has been performed (transfers ownership) */
     1129    m->oldVersion = oldVersion;
    11461130}
    11471131
     
    11871171void XmlTreeBackend::reset()
    11881172{
     1173    RTStrFree (m->oldVersion);
     1174    m->oldVersion = NULL;
     1175
    11891176    if (m->doc)
    11901177    {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette