1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmCPackIFWRepository.h"
4
5 #include <cstddef>
6
7 #include "cmCPackIFWGenerator.h"
8 #include "cmGeneratedFileStream.h"
9 #include "cmSystemTools.h"
10 #include "cmValue.h"
11 #include "cmXMLParser.h"
12 #include "cmXMLWriter.h"
13
cmCPackIFWRepository()14 cmCPackIFWRepository::cmCPackIFWRepository()
15 : Update(cmCPackIFWRepository::None)
16 {
17 }
18
IsValid() const19 bool cmCPackIFWRepository::IsValid() const
20 {
21 bool valid = true;
22
23 switch (this->Update) {
24 case cmCPackIFWRepository::None:
25 case cmCPackIFWRepository::Add:
26 case cmCPackIFWRepository::Remove:
27 valid = !this->Url.empty();
28 break;
29 case cmCPackIFWRepository::Replace:
30 valid = !this->OldUrl.empty() && !this->NewUrl.empty();
31 break;
32 }
33
34 return valid;
35 }
36
ConfigureFromOptions()37 bool cmCPackIFWRepository::ConfigureFromOptions()
38 {
39 // Name;
40 if (this->Name.empty()) {
41 return false;
42 }
43
44 std::string prefix =
45 "CPACK_IFW_REPOSITORY_" + cmsys::SystemTools::UpperCase(this->Name) + "_";
46
47 // Update
48 if (this->IsOn(prefix + "ADD")) {
49 this->Update = cmCPackIFWRepository::Add;
50 } else if (this->IsOn(prefix + "REMOVE")) {
51 this->Update = cmCPackIFWRepository::Remove;
52 } else if (this->IsOn(prefix + "REPLACE")) {
53 this->Update = cmCPackIFWRepository::Replace;
54 } else {
55 this->Update = cmCPackIFWRepository::None;
56 }
57
58 // Url
59 if (cmValue url = this->GetOption(prefix + "URL")) {
60 this->Url = *url;
61 } else {
62 this->Url.clear();
63 }
64
65 // Old url
66 if (cmValue oldUrl = this->GetOption(prefix + "OLD_URL")) {
67 this->OldUrl = *oldUrl;
68 } else {
69 this->OldUrl.clear();
70 }
71
72 // New url
73 if (cmValue newUrl = this->GetOption(prefix + "NEW_URL")) {
74 this->NewUrl = *newUrl;
75 } else {
76 this->NewUrl.clear();
77 }
78
79 // Enabled
80 if (this->IsOn(prefix + "DISABLED")) {
81 this->Enabled = "0";
82 } else {
83 this->Enabled.clear();
84 }
85
86 // Username
87 if (cmValue username = this->GetOption(prefix + "USERNAME")) {
88 this->Username = *username;
89 } else {
90 this->Username.clear();
91 }
92
93 // Password
94 if (cmValue password = this->GetOption(prefix + "PASSWORD")) {
95 this->Password = *password;
96 } else {
97 this->Password.clear();
98 }
99
100 // DisplayName
101 if (cmValue displayName = this->GetOption(prefix + "DISPLAY_NAME")) {
102 this->DisplayName = *displayName;
103 } else {
104 this->DisplayName.clear();
105 }
106
107 return this->IsValid();
108 }
109
110 /** \class cmCPackeIFWUpdatesPatcher
111 * \brief Helper class that parses and patch Updates.xml file (QtIFW)
112 */
113 class cmCPackeIFWUpdatesPatcher : public cmXMLParser
114 {
115 public:
cmCPackeIFWUpdatesPatcher(cmCPackIFWRepository * r,cmXMLWriter & x)116 cmCPackeIFWUpdatesPatcher(cmCPackIFWRepository* r, cmXMLWriter& x)
117 : repository(r)
118 , xout(x)
119 , patched(false)
120 {
121 }
122
123 cmCPackIFWRepository* repository;
124 cmXMLWriter& xout;
125 bool patched;
126
127 protected:
StartElement(const std::string & name,const char ** atts)128 void StartElement(const std::string& name, const char** atts) override
129 {
130 this->xout.StartElement(name);
131 this->StartFragment(atts);
132 }
133
StartFragment(const char ** atts)134 void StartFragment(const char** atts)
135 {
136 for (size_t i = 0; atts[i]; i += 2) {
137 const char* key = atts[i];
138 const char* value = atts[i + 1];
139 this->xout.Attribute(key, value);
140 }
141 }
142
EndElement(const std::string & name)143 void EndElement(const std::string& name) override
144 {
145 if (name == "Updates" && !this->patched) {
146 this->repository->WriteRepositoryUpdates(this->xout);
147 this->patched = true;
148 }
149 this->xout.EndElement();
150 if (this->patched) {
151 return;
152 }
153 if (name == "Checksum") {
154 this->repository->WriteRepositoryUpdates(this->xout);
155 this->patched = true;
156 }
157 }
158
CharacterDataHandler(const char * data,int length)159 void CharacterDataHandler(const char* data, int length) override
160 {
161 std::string content(data, data + length);
162 if (content.empty() || content == " " || content == " " ||
163 content == "\n") {
164 return;
165 }
166 this->xout.Content(content);
167 }
168 };
169
PatchUpdatesXml()170 bool cmCPackIFWRepository::PatchUpdatesXml()
171 {
172 // Lazy directory initialization
173 if (this->Directory.empty() && this->Generator) {
174 this->Directory = this->Generator->toplevel;
175 }
176
177 // Filenames
178 std::string updatesXml = this->Directory + "/repository/Updates.xml";
179 std::string updatesPatchXml =
180 this->Directory + "/repository/UpdatesPatch.xml";
181
182 // Output stream
183 cmGeneratedFileStream fout(updatesPatchXml);
184 cmXMLWriter xout(fout);
185
186 xout.StartDocument();
187
188 this->WriteGeneratedByToStrim(xout);
189
190 // Patch
191 {
192 cmCPackeIFWUpdatesPatcher patcher(this, xout);
193 patcher.ParseFile(updatesXml.data());
194 }
195
196 xout.EndDocument();
197
198 fout.Close();
199
200 return cmSystemTools::RenameFile(updatesPatchXml, updatesXml);
201 }
202
WriteRepositoryConfig(cmXMLWriter & xout) const203 void cmCPackIFWRepository::WriteRepositoryConfig(cmXMLWriter& xout) const
204 {
205 xout.StartElement("Repository");
206
207 // Url
208 xout.Element("Url", this->Url);
209 // Enabled
210 if (!this->Enabled.empty()) {
211 xout.Element("Enabled", this->Enabled);
212 }
213 // Username
214 if (!this->Username.empty()) {
215 xout.Element("Username", this->Username);
216 }
217 // Password
218 if (!this->Password.empty()) {
219 xout.Element("Password", this->Password);
220 }
221 // DisplayName
222 if (!this->DisplayName.empty()) {
223 xout.Element("DisplayName", this->DisplayName);
224 }
225
226 xout.EndElement();
227 }
228
WriteRepositoryUpdate(cmXMLWriter & xout) const229 void cmCPackIFWRepository::WriteRepositoryUpdate(cmXMLWriter& xout) const
230 {
231 xout.StartElement("Repository");
232
233 switch (this->Update) {
234 case cmCPackIFWRepository::None:
235 break;
236 case cmCPackIFWRepository::Add:
237 xout.Attribute("action", "add");
238 break;
239 case cmCPackIFWRepository::Remove:
240 xout.Attribute("action", "remove");
241 break;
242 case cmCPackIFWRepository::Replace:
243 xout.Attribute("action", "replace");
244 break;
245 }
246
247 // Url
248 if (this->Update == cmCPackIFWRepository::Add ||
249 this->Update == cmCPackIFWRepository::Remove) {
250 xout.Attribute("url", this->Url);
251 } else if (this->Update == cmCPackIFWRepository::Replace) {
252 xout.Attribute("oldUrl", this->OldUrl);
253 xout.Attribute("newUrl", this->NewUrl);
254 }
255 // Enabled
256 if (!this->Enabled.empty()) {
257 xout.Attribute("enabled", this->Enabled);
258 }
259 // Username
260 if (!this->Username.empty()) {
261 xout.Attribute("username", this->Username);
262 }
263 // Password
264 if (!this->Password.empty()) {
265 xout.Attribute("password", this->Password);
266 }
267 // DisplayName
268 if (!this->DisplayName.empty()) {
269 xout.Attribute("displayname", this->DisplayName);
270 }
271
272 xout.EndElement();
273 }
274
WriteRepositoryUpdates(cmXMLWriter & xout)275 void cmCPackIFWRepository::WriteRepositoryUpdates(cmXMLWriter& xout)
276 {
277 if (!this->RepositoryUpdate.empty()) {
278 xout.StartElement("RepositoryUpdate");
279 for (cmCPackIFWRepository* r : this->RepositoryUpdate) {
280 r->WriteRepositoryUpdate(xout);
281 }
282 xout.EndElement();
283 }
284 }
285