Changeset 7315 in vbox for trunk/src/VBox/Main/xml/Settings.cpp
- Timestamp:
- Mar 6, 2008 10:12:41 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/xml/Settings.cpp
r7309 r7315 797 797 { 798 798 Data() : ctxt (NULL), doc (NULL) 799 , inputResolver (NULL) {} 799 , inputResolver (NULL) 800 , autoConverter (NULL), oldVersion (NULL) {} 800 801 801 802 xmlParserCtxtPtr ctxt; … … 806 807 InputResolver *inputResolver; 807 808 809 AutoConverter *autoConverter; 810 char *oldVersion; 811 808 812 std::auto_ptr <stdx::exception_trap_base> trappedErr; 809 810 struct AutoConv811 {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;831 813 832 814 /** … … 896 878 } 897 879 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); 880 void XmlTreeBackend::setAutoConverter (AutoConverter &aConverter) 881 { 882 m->autoConverter = &aConverter; 883 } 884 885 void XmlTreeBackend::resetAutoConverter() 886 { 887 m->autoConverter = NULL; 888 } 889 890 const char *XmlTreeBackend::oldVersion() const 891 { 892 return m->oldVersion; 914 893 } 915 894 … … 957 936 } 958 937 938 char *oldVersion = NULL; 939 959 940 /* perform automatic document transformation if necessary */ 960 if ( !m->autoConv.isNull())941 if (m->autoConverter != NULL) 961 942 { 962 943 Key root = Key (new XmlKeyBackend (xmlDocGetRootElement (doc))); 963 if ( !strcmp (root.name(), m->autoConv.root))944 if (m->autoConverter->needsConversion (root, oldVersion)) 964 945 { 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 967 952 { 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 */ 976 954 { 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) 1026 1018 xsltFreeTransformContext (tranCtxt); 1027 1019 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) 1030 1023 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; 1052 1030 } 1053 1031 } … … 1130 1108 xmlSchemaFreeParserCtxt (schemaCtxt); 1131 1109 1110 RTStrFree (oldVersion); 1111 1132 1112 throw; 1133 1113 } … … 1144 1124 /* assign the root key */ 1145 1125 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; 1146 1130 } 1147 1131 … … 1187 1171 void XmlTreeBackend::reset() 1188 1172 { 1173 RTStrFree (m->oldVersion); 1174 m->oldVersion = NULL; 1175 1189 1176 if (m->doc) 1190 1177 {
Note:
See TracChangeset
for help on using the changeset viewer.