00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013
00014
00015 #include "wx/wxprec.h"
00016
00017 #ifdef __BORLANDC__
00018 #pragma hdrstop
00019 #endif
00020
00021 #ifndef WX_PRECOMP
00022 #include "wx/wx.h"
00023 #endif
00024
00025
00026 #include <wx/fileconf.h>
00027 #include <wx/mstream.h>
00028 #include <wx/apptrait.h>
00029 #include <wx/zstream.h>
00030
00031 #if wxUSE_GUI
00032 #include <wx/progdlg.h>
00033 #endif
00034
00035 #include "wxp/wxp.h"
00036 #include "wxp/packagewxp.h"
00037
00038
00039
00040 IMPLEMENT_DYNAMIC_CLASS(wxPackageXML, wxXmlDocument)
00041 IMPLEMENT_DYNAMIC_CLASS(wxPresetXMLDescriptor, wxPackageXML)
00042 IMPLEMENT_DYNAMIC_CLASS(wxPackageRepositoryXMLDescriptor, wxXmlDocument)
00043
00044
00045 wxPackageCommandOptionArrayHashMap wxPresetXMLDescriptor::s_hashmapOptions;
00046 wxPackageCommandSetHashMap wxPresetXMLDescriptor::s_hashmapCommands;
00047
00048
00049
00050
00051
00052
00053
00054 void wxPackageXML::HandleUnknownTag(wxXmlNode *node)
00055 {
00056 if (node->GetType() != wxXML_COMMENT_NODE &&
00057 (node->GetType() != wxXML_TEXT_NODE || !node->IsWhitespaceOnly()))
00058 {
00059 wxLogWarning(wxT("Discarding unknown/misplaced tag <%s> found in <%s>"),
00060 node->GetName().c_str(), node->GetParent()->GetName().c_str());
00061
00062
00063
00064 node->GetParent()->RemoveChild(node);
00065 }
00066 }
00067
00068 wxString wxPackageXML::GetStrippedNodeContent(const wxXmlNode *n) const
00069 {
00070
00071
00072
00073 wxString str = n->GetNodeContent();
00074
00075
00076 return str.Strip(wxString::both);
00077 }
00078
00079 wxPackageCondition wxPackageXML::LoadCondition(const wxXmlNode *n)
00080 {
00081 wxString buildsys(n->GetPropVal(wxT("buildsys"), wxEmptyString));
00082 wxString formats(n->GetPropVal(wxT("formats"), wxEmptyString));
00083 wxString platforms(n->GetPropVal(wxT("platforms"), wxEmptyString));
00084 wxString stages(n->GetPropVal(wxT("stages"), wxEmptyString));
00085
00086
00087 long b = wxString2PackageBuildSystemTypeList(buildsys);
00088 long f = wxString2PackageCompilerFormatList(formats);
00089 long p = wxString2PortIdList(platforms);
00090 long s = wxString2PackageBuildSystemStageList(stages);
00091
00092
00093
00094
00095 if (b == 0) b = wxGetFullPackageBuildSystemTypeList();
00096 if (f == 0) f = wxGetFullPackageCompilerFormatList();
00097 if (p == 0) p = wxGetFullPortIdList();
00098 if (s == 0) s = wxGetFullPackageBuildSystemStageList();
00099
00100 return wxPackageCondition(p, f, b, s);
00101 }
00102
00103 wxPackageCommandOptionArray wxPackageXML::LoadOptions(const wxXmlNode *n)
00104 {
00105
00106 if (n->GetName() != wxT("option-set") &&
00107 n->GetName() != wxT("options"))
00108 return wxEmptyPackageCommandOptionArray;
00109
00110 wxPackageCommandOptionArray ret;
00111 wxXmlNode *cond = n->GetChildren();
00112 while (cond)
00113 {
00114 if (cond->GetName() == wxT("if"))
00115 {
00116 wxPackageCondition c = LoadCondition(cond);
00117
00118
00119
00120
00121
00122 wxXmlNode *optnode = cond->GetChildren();
00123 while (optnode)
00124 {
00125 if (optnode->GetName() == wxT("option"))
00126 {
00127 wxPackageCommandOption opt = LoadOption(optnode);
00128 opt.SetCondition(c);
00129
00130
00131
00132 if (opt.IsOk())
00133 ret.Add(opt);
00134 else
00135 wxLogWarning(wxT("Discarding invalid option named '%s'"),
00136 opt.GetName().c_str());
00137 }
00138 else
00139 HandleUnknownTag(optnode);
00140
00141 optnode = optnode->GetNext();
00142 }
00143 }
00144 else if (cond->GetName() == wxT("option"))
00145 {
00146
00147
00148 wxPackageCommandOption opt = LoadOption(cond);
00149 if (opt.IsOk())
00150 ret.Add(opt);
00151 else
00152 wxLogWarning(wxT("Discarding invalid option named '%s'"),
00153 opt.GetName().c_str());
00154 }
00155 else
00156 HandleUnknownTag(cond);
00157
00158
00159 cond = cond->GetNext();
00160 }
00161
00162 return ret;
00163 }
00164
00165 wxPackageCommandOption wxPackageXML::LoadOption(const wxXmlNode *n)
00166 {
00167 if (n->GetName() != wxT("option") ||
00168 !n->HasProp(wxT("name")))
00169 return wxEmptyPackageCommandOption;
00170
00171 wxString name(n->GetPropVal(wxT("name"), wxEmptyString));
00172 wxString category(n->GetPropVal(wxT("category"), wxEmptyString));
00173 wxString defvalue, description, group, values, valuesdesc, value;
00174
00175 wxXmlNode *child = n->GetChildren();
00176 while (child)
00177 {
00178 if (child->GetName() == wxT("default-value"))
00179 {
00180 defvalue = GetStrippedNodeContent(child);
00181 }
00182 else if (child->GetName() == wxT("description"))
00183 {
00184 description = GetStrippedNodeContent(child);
00185 description.Trim(false);
00186 description.Trim(true);
00187 }
00188 else if (child->GetName() == wxT("group"))
00189 {
00190 group = GetStrippedNodeContent(child);
00191 }
00192 else if (child->GetName() == wxT("values"))
00193 {
00194 values = GetStrippedNodeContent(child);
00195 }
00196 else if (child->GetName() == wxT("values-description"))
00197 {
00198 valuesdesc = GetStrippedNodeContent(child);
00199 }
00200 else if (child->GetName() == wxT("value"))
00201 {
00202
00203
00204
00205
00206 value = GetStrippedNodeContent(child);
00207 }
00208 else
00209 HandleUnknownTag(child);
00210
00211
00212 child = child->GetNext();
00213 }
00214
00215
00216 if (group == wxEmptyString)
00217 group = wxT("Ungrouped");
00218 if (value == wxEmptyString)
00219 value = defvalue;
00220
00221
00222 wxPackageCommandOptionCategory cat = wxString2PackageCommandOptionCategory(category);
00223 wxPackageCommandOption opt(name, values, value, defvalue, valuesdesc,
00224 description, group, cat);
00225
00226
00227 if (cat == wxPCOC_INVALID && !n->HasProp(wxT("category")))
00228 opt.AutodetectCategory();
00229
00230
00231
00232
00233 opt.GetCondition().SetAlwaysTrue();
00234
00235 return opt;
00236 }
00237
00238 wxPackageCommand wxPackageXML::LoadCommand(const wxXmlNode *n)
00239 {
00240 wxPackageCommand ret(GetStrippedNodeContent(n),
00241 n->GetPropVal(wxT("path"), wxEmptyString));
00242
00243
00244
00245
00246 ret.GetCondition().SetAlwaysTrue();
00247 return ret;
00248 }
00249
00250 wxXmlNode *wxPackageXML::AddChildIndentation(wxXmlNode *node, int level)
00251 {
00252 wxASSERT(node);
00253 if (m_nIndentationStep < 0)
00254 return node->GetChildren();
00255
00256 wxXmlNode *indent = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString,
00257 wxT("\n") + wxString(wxT(' '),
00258 level*m_nIndentationStep));
00259 node->AddChild(indent);
00260 return indent;
00261 }
00262
00263 wxXmlNode *wxPackageXML::InsertChildIndentation(wxXmlNode *node,
00264 wxXmlNode *before_node,
00265 int level)
00266 {
00267 wxASSERT(node);
00268 if (m_nIndentationStep < 0)
00269 return node->GetChildren();
00270
00271 wxXmlNode *indent = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString,
00272 wxT("\n") + wxString(wxT(' '),
00273 level*m_nIndentationStep));
00274 node->InsertChild(indent, before_node);
00275 return indent;
00276 }
00277
00278 wxXmlNode *wxPackageXML::AddSiblingIndentation(wxXmlNode *node, int level)
00279 {
00280 wxASSERT(node);
00281 if (m_nIndentationStep < 0)
00282 return node;
00283
00284 wxXmlNode *indent = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString,
00285 wxT("\n") + wxString(wxT(' '),
00286 level*m_nIndentationStep));
00287 indent->SetParent(node->GetParent());
00288
00289 wxXmlNode *oldnext = node->GetNext();
00290 node->SetNext(indent);
00291 indent->SetNext(oldnext);
00292 return indent;
00293 }
00294
00295 wxXmlNode *wxPackageXML::SaveCondition(const wxPackageCondition &cond, int WXUNUSED(level))
00296 {
00297
00298
00299
00300
00301 wxXmlNode *ret = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("if"));
00302
00303 wxString fmt,plat,bs,stages;
00304
00305 if (cond.GetFormats() != wxGetFullPackageCompilerFormatList())
00306 fmt = cond.GetFormatsStr();
00307 if (cond.GetPlatforms() != wxGetFullPortIdList())
00308 plat = cond.GetPlatformsStr();
00309 if (cond.GetBuildSystems() != wxGetFullPackageBuildSystemTypeList())
00310 bs = cond.GetBuildSystemsStr();
00311 if (cond.GetStages() != wxGetFullPackageBuildSystemStageList())
00312 stages = cond.GetStagesStr();
00313
00314 if (!fmt.IsEmpty()) ret->AddProperty(wxT("formats"), fmt.Lower());
00315 if (!plat.IsEmpty()) ret->AddProperty(wxT("platforms"), plat.Lower());
00316 if (!bs.IsEmpty()) ret->AddProperty(wxT("buildsys"), bs.Lower());
00317 if (!stages.IsEmpty()) ret->AddProperty(wxT("stages"), stages.Lower());
00318
00319 return ret;
00320 }
00321
00322 wxXmlNode *wxPackageXML::SaveOption(const wxPackageCommandOption &opt, int level)
00323 {
00324 #define wxADD_CHILD_WITH_TEXT(name, text) \
00325 if (!text.IsEmpty()) \
00326 { \
00327 wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, name); \
00328 node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, name, text)); \
00329 AddChildIndentation(optnode, level+1); \
00330 optnode->AddChild(node); \
00331 }
00332
00333 wxXmlNode *optnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("option"));
00334 optnode->AddProperty(wxT("name"), opt.GetName());
00335
00336 if (opt.GetCategory() != wxPCOC_LISTED_VALUES)
00337 optnode->AddProperty(wxT("category"),
00338 wxPackageCommandOptionCategory2String(opt.GetCategory()));
00339
00340
00341 if (opt.IsChanged())
00342 wxADD_CHILD_WITH_TEXT(wxT("value"), opt.GetValue());
00343
00344 wxADD_CHILD_WITH_TEXT(wxT("default-value"), opt.GetDefaultValue());
00345 wxADD_CHILD_WITH_TEXT(wxT("values"), opt.GetAllowedValues());
00346 wxADD_CHILD_WITH_TEXT(wxT("values-description"), opt.GetValueDesc());
00347 wxADD_CHILD_WITH_TEXT(wxT("description"), opt.GetDescription());
00348 wxADD_CHILD_WITH_TEXT(wxT("group"), opt.GetGroup());
00349 AddChildIndentation(optnode, level);
00350
00351 return optnode;
00352 }
00353
00354 wxXmlNode *wxPackageXML::SaveCommand(const wxPackageCommand &cmd, int WXUNUSED(level))
00355 {
00356
00357
00358
00359
00360 wxXmlNode *cmdnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("cmd"));
00361 cmdnode->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxT("cmd"), cmd.GetCommand()));
00362
00363 if (!cmd.GetWorkingPath().IsEmpty())
00364 cmdnode->AddProperty(wxT("path"), cmd.GetWorkingPath());
00365 return cmdnode;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 void wxIfNodeListManager::SmartAppend(wxXmlNode *n, const wxPackageCondition &cnd, int level)
00377 {
00378 if (m_previousif == NULL)
00379 {
00380
00381 if (cnd != wxEmptyPackageCondition && !cnd.IsAlwaysTrue())
00382 {
00383
00384 m_previouscond = cnd;
00385 m_previousif = m_doc->SaveCondition(cnd, level);
00386
00387
00388 m_previousif->AddChild(n);
00389
00390
00391 m_doc->AddChildIndentation(m_parent, level);
00392 m_parent->AddChild(m_previousif);
00393 }
00394 else
00395 {
00396
00397 m_doc->AddChildIndentation(m_parent, level);
00398 m_parent->AddChild(n);
00399
00400
00401 wxASSERT(m_previouscond == wxEmptyPackageCondition);
00402 }
00403 }
00404 else
00405 {
00406
00407 if (cnd != wxEmptyPackageCondition && !cnd.IsAlwaysTrue())
00408 {
00409 if (cnd != m_previouscond)
00410 {
00411
00412 m_previouscond = cnd;
00413 m_previousif = m_doc->SaveCondition(cnd, level);
00414
00415
00416 m_doc->AddChildIndentation(m_previousif, level+1);
00417 m_previousif->AddChild(n);
00418 m_doc->AddChildIndentation(m_previousif, level+1);
00419
00420 m_parent->AddChild(m_previousif);
00421 }
00422 else
00423 {
00424
00425 m_doc->AddChildIndentation(m_previousif, level+1);
00426 m_previousif->AddChild(n);
00427 m_doc->AddChildIndentation(m_previousif, level+1);
00428
00429 m_previouscond = cnd;
00430 }
00431 }
00432 else
00433 {
00434
00435 m_doc->AddChildIndentation(m_previousif, level);
00436 m_parent->AddChild(n);
00437 m_doc->AddChildIndentation(m_previousif, level);
00438
00439 m_previousif = NULL;
00440 m_previouscond = wxEmptyPackageCondition;
00441 }
00442 }
00443 }
00444
00445 void wxIfNodeListManager::SaveOptions(const wxPackageCommandOptionArray &arr, int level)
00446 {
00447 for (size_t i=0; i < arr.GetCount(); i++)
00448 {
00449
00450
00451 wxXmlNode *newnode = m_doc->SaveOption(arr[i], level);
00452 SmartAppend(newnode, arr[i].GetCondition(), level);
00453 }
00454 }
00455
00456 void wxIfNodeListManager::SaveCommands(const wxPackageCommandArray &arr, int level)
00457 {
00458 for (size_t i=0; i < arr.GetCount(); i++)
00459 {
00460
00461
00462 wxXmlNode *newnode = m_doc->SaveCommand(arr[i], level);
00463 SmartAppend(newnode, arr[i].GetCondition(), level);
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474 #ifdef __WXDEBUG__
00475
00476 void wxPresetXMLDescriptor::Dump()
00477 {
00478
00479 wxPackageCommandOptionArrayHashMap::iterator it;
00480 for( it = s_hashmapOptions.begin(); it != s_hashmapOptions.end(); ++it )
00481 {
00482 wxString key = it->first;
00483 wxPackageCommandOptionArray &value = it->second;
00484
00485 for (size_t i=0; i<value.GetCount(); i++)
00486 wxLogDebug(wxT("Optionset [%s] - option '%s' - default value '%s'"),
00487 key.c_str(), value[i].GetName().c_str(),
00488 value[i].GetDefaultValue().c_str());
00489 }
00490
00491
00492 wxPackageCommandSetHashMap::iterator it2;
00493 for( it2 = s_hashmapCommands.begin(); it2 != s_hashmapCommands.end(); ++it2 )
00494 {
00495 wxString key = it2->first;
00496 wxPackageCommandSet &value = it2->second;
00497
00498 for (size_t i=0; i<value.GetCount(); i++)
00499 wxLogDebug(wxT("Commandset [%s] - command '%s'"),
00500 key.c_str(), value[i].GetCommand().c_str());
00501 }
00502 }
00503 #endif
00504
00505
00506 bool wxPresetXMLDescriptor::Load(const wxString &filename)
00507 {
00508 wxFileInputStream stream(filename);
00509 if (!stream.Ok())
00510 return false;
00511
00512
00513
00514 wxPresetXMLDescriptor doc;
00515 return doc.Load(stream);
00516 }
00517
00518 bool wxPresetXMLDescriptor::Load(wxInputStream &input)
00519 {
00520 wxXmlDocument doc;
00521
00522 if (!doc.Load(input))
00523 return false;
00524
00525 if (!doc.GetRoot() ||
00526 doc.GetRoot()->GetName() != wxT("wxpackage-presets") ||
00527 doc.GetRoot()->GetPropVal(wxT("version"), wxT("1.0")) != wxT("1.0"))
00528 return false;
00529
00530 wxXmlNode *child = doc.GetRoot()->GetChildren();
00531 while (child)
00532 {
00533 if (child->GetName() == wxT("option-set") &&
00534 child->HasProp(wxT("name")))
00535 {
00536
00537 wxString name = child->GetPropVal(wxT("name"), wxEmptyString);
00538 wxString desc = child->GetPropVal(wxT("description"), wxEmptyString);
00539
00540
00541 wxPackageCommandOptionArray preset(LoadOptions(child));
00542 preset.SetDescription(desc);
00543
00544 if (preset.IsOk())
00545 s_hashmapOptions[name] = preset;
00546 else
00547 wxLogWarning(wxT("Discarding invalid option set named '%s'"),
00548 name.c_str());
00549 }
00550 else if (child->GetName() == wxT("command-set") &&
00551 child->HasProp(wxT("name")))
00552 {
00553
00554 wxString name = child->GetPropVal(wxT("name"), wxEmptyString);
00555 wxString desc = child->GetPropVal(wxT("description"), wxEmptyString);
00556
00557
00558 wxPackageCommandSet cmdset(LoadCommandSet(child));
00559 cmdset.SetDescription(desc);
00560
00561 if (cmdset.IsOk())
00562 s_hashmapCommands[name] = cmdset;
00563 else
00564 wxLogWarning(wxT("Discarding invalid command set named '%s'"),
00565 name.c_str());
00566 }
00567 else
00568 HandleUnknownTag(child);
00569
00570
00571 child = child->GetNext();
00572 }
00573
00574 return true;
00575 }
00576
00577 wxPackageCommandSet wxPresetXMLDescriptor::LoadCommandSet(const wxXmlNode *n)
00578 {
00579 wxPackageCommandSet ret;
00580
00581 wxString buildsys = n->GetPropVal(wxT("buildsys"), wxEmptyString);
00582 wxString vars = n->GetPropVal(wxT("vars"), wxEmptyString);
00583
00584 ret.SetBuildSystemType(wxString2PackageBuildSystemType(buildsys));
00585 ret.SetVars(vars);
00586
00587 wxXmlNode *child = n->GetChildren();
00588 while (child)
00589 {
00590 if (child->GetName() == wxT("if"))
00591 {
00592 wxPackageCondition current = LoadCondition(child);
00593
00594
00595
00596
00597 if (!child->HasProp(wxT("buildsys")))
00598 {
00599 wxXmlNode *cmd = child->GetChildren();
00600 while (cmd)
00601 {
00602 if (cmd->GetName() == wxT("cmd"))
00603 {
00604 wxPackageCommand c(LoadCommand(cmd));
00605 c.SetCondition(current);
00606 if (c.IsOk())
00607 ret.Add(c);
00608 else
00609 wxLogWarning(wxT("Discarding invalid <cmd> '%s'"),
00610 c.GetCommand().c_str());
00611 }
00612 else
00613 HandleUnknownTag(cmd);
00614
00615 cmd = cmd->GetNext();
00616 }
00617 }
00618 else
00619 wxLogWarning(wxT("Discarding invalid <if> command"));
00620 }
00621 else if (child->GetName() == wxT("cmd"))
00622 {
00623 wxPackageCommand c(LoadCommand(child));
00624 if (c.IsOk())
00625 ret.Add(c);
00626 else
00627 wxLogWarning(wxT("Discarding invalid <cmd> '%s'"),
00628 c.GetCommand().c_str());
00629 }
00630 else
00631 HandleUnknownTag(child);
00632
00633
00634 child = child->GetNext();
00635 }
00636
00637 return ret;
00638 }
00639
00640
00641 bool wxPresetXMLDescriptor::SavePresets(const wxString &filename)
00642 {
00643
00644
00645
00646
00647
00648 bool allclean = true;
00649 for( wxPackageCommandOptionArrayHashMap::iterator it = s_hashmapOptions.begin();
00650 it != s_hashmapOptions.end(); ++it )
00651 {
00652 if (s_hashmapOptions[it->first].IsDirty())
00653 {
00654 allclean = false;
00655 break;
00656 }
00657 }
00658
00659 if (allclean)
00660 return true;
00661
00662 wxFileOutputStream stream(filename);
00663 if (!stream.Ok())
00664 return false;
00665
00666
00667
00668 wxPresetXMLDescriptor doc;
00669 return doc.SavePresets(stream);
00670 }
00671
00672 bool wxPresetXMLDescriptor::SavePresets(wxOutputStream &out)
00673 {
00674 wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("wxpackage-presets"));
00675 root->AddProperty(wxT("version"), wxT("1.0"));
00676
00677
00678 root->AddChild(new wxXmlNode(wxXML_COMMENT_NODE, wxEmptyString,
00679 wxString::Format(wxT(" Preset file for the wxWidgets Package Manager. Automatically generated in date %s. "),
00680 wxDateTime::Now().Format(wxT("%d %b %Y")).c_str())));
00681 root->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\n")));
00682
00683
00684 root->AddChild(new wxXmlNode(wxXML_COMMENT_NODE, wxEmptyString,
00685 wxT(" The option presets: ")));
00686 for( wxPackageCommandOptionArrayHashMap::iterator it = s_hashmapOptions.begin();
00687 it != s_hashmapOptions.end(); ++it )
00688 {
00689 wxPackageCommandOptionArray &arr = it->second;
00690
00691
00692 if (arr.GetCount() == 0)
00693 continue;
00694
00695 wxXmlNode *child = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("option-set"));
00696 child->AddProperty(wxT("name"), it->first);
00697 child->AddProperty(wxT("description"), arr.GetDescription());
00698
00699
00700 wxIfNodeListManager list(this, child);
00701 list.SaveOptions(arr);
00702
00703
00704 root->AddChild(child);
00705 }
00706
00707
00708 root->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\n")));
00709 root->AddChild(new wxXmlNode(wxXML_COMMENT_NODE, wxEmptyString,
00710 wxT(" The command presets: ")));
00711 for( wxPackageCommandSetHashMap::iterator it = s_hashmapCommands.begin();
00712 it != s_hashmapCommands.end(); ++it )
00713 {
00714 wxPackageCommandSet &arr = it->second;
00715
00716
00717 if (arr.GetCount() == 0)
00718 continue;
00719
00720 wxXmlNode *child = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("command-set"));
00721 child->AddProperty(wxT("name"), it->first);
00722 child->AddProperty(wxT("description"), arr.GetDescription());
00723
00724
00725 child->AddProperty(wxT("vars"),
00726 wxArray2String(arr.GetVars()));
00727 child->AddProperty(wxT("buildsys"),
00728 wxPackageBuildSystemType2String(arr.GetBuildSystemType()));
00729
00730
00731 wxIfNodeListManager list(this, child);
00732 list.SaveCommands(arr);
00733
00734
00735 root->AddChild(child);
00736 }
00737
00738
00739 wxXmlDocument doc;
00740 doc.SetRoot(root);
00741 return doc.Save(out, 2 );
00742 }
00743
00744
00745
00746
00747
00748
00749
00750 bool wxPackageRepositoryXMLDescriptor::Load(const wxString &filename)
00751 {
00752 wxFFileInputStream input(filename);
00753 if (!input.IsOk())
00754 return false;
00755
00756
00757 wxZlibInputStream unzipped(input);
00758 return wxPackageXML::Load(unzipped);
00759 }
00760
00761 bool wxPackageRepositoryXMLDescriptor::AddPackage(const wxString &pkgfile)
00762 {
00763 wxPackage pkg;
00764 if (!pkg.LoadCompressedPackage(pkgfile))
00765 {
00766 wxLogError(wxT("Cannot load the '%s' package."), pkgfile.c_str());
00767 return false;
00768 }
00769
00770
00771
00772
00773 if (!GetRoot())
00774 {
00775
00776 SetRoot(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("wxpackagelist")));
00777 GetRoot()->AddProperty(wxT("version"), wxT("1.0"));
00778 }
00779
00780
00781
00782
00783
00784 wxPackageXMLDescriptor wxp;
00785 wxp.SetPackageInfo(pkg);
00786
00787
00788
00789 wxXmlNode *root = wxp.DetachRoot();
00790 GetRoot()->AddChild(root);
00791
00792 root->AddProperty(wxT("size"), pkg.GetCompressedSize().ToString());
00793 root->AddProperty(wxT("md5"), pkg.GetMD5());
00794 root->AddProperty(wxT("file"), wxFileName(pkgfile).GetFullName());
00795
00796 return true;
00797 }
00798
00799 wxPackageArray wxPackageRepositoryXMLDescriptor::GetPackageArray(const wxString &repourl)
00800 {
00801 wxPackageArray ret;
00802
00803
00804 if (!GetRoot() ||
00805 GetRoot()->GetName() != wxT("wxpackagelist") ||
00806 GetRoot()->GetPropVal(wxT("version"), wxT("1.0")) != wxT("1.0"))
00807 return wxEmptyPackageArray;
00808
00809
00810
00811
00812 wxString baseurl = repourl.BeforeLast(wxT('/'));
00813
00814 wxXmlNode *child = GetRoot()->GetChildren();
00815 while (child)
00816 {
00817 if (child->GetName() == wxT("wxpackage"))
00818 {
00819 wxPackageXMLDescriptor wxp;
00820
00821
00822 wxp.SetRoot(child);
00823
00824
00825 if (wxp.Parse())
00826 {
00827
00828
00829
00830 wxPackage pkg(wxp.GetPackageInfo());
00831
00832 wxString url, filename = child->GetPropVal(wxT("file"), wxEmptyString);
00833 if (!baseurl.IsEmpty() && !filename.IsEmpty())
00834 url = baseurl + wxT("/") + filename;
00835
00836 pkg.SetRepoDownloadLink(url);
00837 pkg.SetMD5(child->GetPropVal(wxT("md5"), wxEmptyString));
00838
00839 if (child->HasProp(wxT("size")))
00840 {
00841 unsigned long sz;
00842 if (child->GetPropVal(wxT("size"), wxEmptyString).ToULong(&sz))
00843 pkg.SetCompressedSize(sz);
00844 }
00845
00846 if (pkg.IsOk())
00847 {
00848 pkg.SetRemoteStatus();
00849 ret.Add(pkg);
00850 }
00851 else
00852 wxLogWarning(wxT("Discarding invalid package named '%s'"),
00853 pkg.GetName().c_str());
00854 }
00855
00856
00857
00858 wxp.DetachRoot();
00859 }
00860 else
00861 HandleUnknownTag(child);
00862
00863
00864 child = child->GetNext();
00865 }
00866
00867 if (!ret.IsOk())
00868 return wxEmptyPackageArray;
00869 return ret;
00870 }
00871