Update license; improve coverage; add docs dir
[portal.git] / ecomp-portal-widget-ms / widget-ms / src / main / java / org / openecomp / portalapp / widget / service / impl / StorageServiceImpl.java
1 /*-
2  * ============LICENSE_START==========================================
3  * ONAP Portal
4  * ===================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * ===================================================================
7  *
8  * Unless otherwise specified, all software contained herein is licensed
9  * under the Apache License, Version 2.0 (the “License”);
10  * you may not use this software except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *             http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * Unless otherwise specified, all documentation contained herein is licensed
22  * under the Creative Commons License, Attribution 4.0 Intl. (the “License”);
23  * you may not use this documentation except in compliance with the License.
24  * You may obtain a copy of the License at
25  *
26  *             https://creativecommons.org/licenses/by/4.0/
27  *
28  * Unless required by applicable law or agreed to in writing, documentation
29  * distributed under the License is distributed on an "AS IS" BASIS,
30  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  * See the License for the specific language governing permissions and
32  * limitations under the License.
33  *
34  * ============LICENSE_END============================================
35  *
36  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
37  */
38 package org.openecomp.portalapp.widget.service.impl;
39
40 import java.io.File;
41 import java.io.FileOutputStream;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.io.UnsupportedEncodingException;
45 import java.nio.file.Files;
46 import java.nio.file.Paths;
47 import java.util.Arrays;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.regex.Matcher;
51 import java.util.regex.Pattern;
52 import java.util.zip.ZipEntry;
53 import java.util.zip.ZipOutputStream;
54
55 import org.hibernate.Criteria;
56 import org.hibernate.Session;
57 import org.hibernate.SessionFactory;
58 import org.hibernate.Transaction;
59 import org.hibernate.criterion.Restrictions;
60 import org.openecomp.portalapp.widget.constant.WidgetConstant;
61 import org.openecomp.portalapp.widget.domain.ValidationRespond;
62 import org.openecomp.portalapp.widget.domain.WidgetCatalog;
63 import org.openecomp.portalapp.widget.domain.WidgetFile;
64 import org.openecomp.portalapp.widget.excetpion.StorageException;
65 import org.openecomp.portalapp.widget.service.StorageService;
66 import org.openecomp.portalapp.widget.service.WidgetCatalogService;
67 import org.openecomp.portalapp.widget.utils.UnzipUtil;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70 import org.springframework.beans.factory.annotation.Autowired;
71 import org.springframework.stereotype.Service;
72 import org.springframework.transaction.annotation.Transactional;
73 import org.springframework.web.multipart.MultipartFile;
74
75 @Service
76 public class StorageServiceImpl implements StorageService {
77
78         private static final Logger logger = LoggerFactory.getLogger(StorageServiceImpl.class);
79
80         @Autowired
81         private SessionFactory sessionFactory;
82
83         @Autowired
84         WidgetCatalogService widgetCatalogService;
85
86         @Override
87         @Transactional
88         public void deleteWidgetFile(long widgetId) {
89                 WidgetFile widgetFile = getWidgetFile(widgetId);
90                 logger.debug("StorageServiceImpl.deleteWidgetFile: deleting widget file {}", widgetId);
91                 if (widgetFile == null) {
92                         logger.debug(
93                                         "StorageServiceImpl.deleteWidgetFile: No widget file found in database while performing StorageServiceImpl.deleteWidgetFile.");
94                         return;
95                 }
96                 Session session = sessionFactory.getCurrentSession();
97                 Transaction tx = session.beginTransaction();
98                 session.delete(widgetFile);
99                 tx.commit();
100         }
101
102         @Override
103         @SuppressWarnings("unchecked")
104         @Transactional
105         public WidgetFile getWidgetFile(long widgetId) {
106                 logger.debug("StorageServiceImpl.getWidgetFile: getting widget file {}", widgetId);
107                 WidgetFile widgetFile = null;
108                 Session session = sessionFactory.openSession();
109                 Criteria criteria = session.createCriteria(WidgetFile.class);
110                 criteria.add(Restrictions.eq("widgetId", widgetId));
111                 List<WidgetFile> widgetFiles = criteria.list();
112                 session.flush();
113                 session.close();
114                 if (widgetFiles.size() > 0)
115                         widgetFile = widgetFiles.get(0);
116                 return widgetFile;
117         }
118
119         @Override
120         public ValidationRespond checkZipFile(MultipartFile file) {
121                 StringBuilder error_msg = new StringBuilder();
122                 UnzipUtil unzipper = new UnzipUtil();
123                 Map<String, byte[]> map;
124                 File convFile;
125                 boolean isValid = true;
126                 if (!file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')).equals(".zip")) {
127                         isValid = false;
128                         error_msg.append(WidgetConstant.VALIDATION_MESSAGE_ZIP);
129                         logger.error("StorageServiceImpl.checkZipFile: invalid file format");
130                 }
131                 try {
132                         if (file.isEmpty()) {
133                                 logger.error(
134                                                 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
135                                 throw new StorageException(
136                                                 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
137                         }
138                         String fileLocation = file.getOriginalFilename();
139                         logger.debug("StorageServiceImpl.checkZipFile: store the widget to:" + fileLocation);
140                         convFile = new File(fileLocation);
141                         FileOutputStream fos = new FileOutputStream(convFile);
142                         fos.write(file.getBytes());
143                         fos.close();
144                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
145                         convFile.delete();
146                 } catch (IOException e) {
147                         logger.error("StorageServiceImpl.checkZipFile: Failed to store file " + file.getOriginalFilename(), e);
148                         throw new StorageException(
149                                         "torageServiceImpl.checkZipFile: Failed to store file " + file.getOriginalFilename(), e);
150                 }
151
152                 for (byte[] b : map.values()) {
153                         if (isValid && b == null) {
154                                 isValid = false;
155                                 error_msg.append(WidgetConstant.VALIDATION_MESSAGE_FILES);
156                                 break;
157                         }
158                 }
159                 return new ValidationRespond(isValid, error_msg.toString());
160         }
161
162         @Override
163         @Transactional
164         public void save(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
165
166                 UnzipUtil unzipper = new UnzipUtil();
167                 Map<String, byte[]> map;
168                 File convFile;
169                 try {
170                         if (file.isEmpty()) {
171                                 logger.error("Failed to store empty file " + file.getOriginalFilename());
172                                 throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
173                         }
174                         String fileLocation = file.getOriginalFilename();
175                         logger.debug("StorageServiceImpl.save: store the widget to:" + fileLocation);
176                         convFile = new File(fileLocation);
177                         FileOutputStream fos = new FileOutputStream(convFile);
178                         fos.write(file.getBytes());
179                         fos.close();
180                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
181                         convFile.delete();
182                 } catch (IOException e) {
183                         logger.error("StorageServiceImpl.save: Failed to store file " + file.getOriginalFilename(), e);
184                         throw new StorageException("Failed to store file " + file.getOriginalFilename(), e);
185                 }
186                 saveHelper(newWidget, widgetId, map);
187         }
188
189         @Override
190         @Transactional
191         public void initSave(File file, WidgetCatalog newWidget, long widgetId) {
192
193                 UnzipUtil unzipper = new UnzipUtil();
194                 Map<String, byte[]> map;
195
196                 try {
197                         String fileLocation = file.getPath();
198                         logger.debug("StorageServiceImpl.save: store the widget to:" + fileLocation);
199                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
200                 } catch (IOException e) {
201                         logger.error("StorageServiceImpl.save: Failed to store file " + file.getName(), e);
202                         throw new StorageException("Failed to store file " + file.getName(), e);
203                 }
204                 
205                 saveHelper(newWidget, widgetId, map);
206         }
207
208         /**
209          * Helper method for saving widget files (controller.js, framework.js,
210          * markup.html and style.css) to ep_widget_catalog_files table in database
211          * 
212          * @param newWidget
213          * @param widgetId
214          * @param map
215          */
216         private void saveHelper(WidgetCatalog newWidget, long widgetId, Map<String, byte[]> map) {
217
218                 logger.debug("Going to save widget " + newWidget);
219                 WidgetFile widgetFile = new WidgetFile();
220                 widgetFile.setName(newWidget.getName());
221                 widgetFile.setWidgetId(widgetId);
222
223                 InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js");
224
225                 String sb = null;
226                 try {
227                         byte[] bytes = new byte[fileInputStream.available()];
228                         fileInputStream.read(bytes);
229                         sb = new String(bytes, "UTF-8");
230                 } catch (IOException e) {
231                         logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
232                         e.printStackTrace();
233                 } finally {
234                         if (fileInputStream != null) {
235                                 try {
236                                         fileInputStream.close();
237                                 } catch (IOException e) {
238                                         logger.error("StorageServiceImpl.update: Failed to close the fileInputStream ", e);
239                                 }
240                         }
241                 }
242
243                 String namespace = "Portal" + widgetId + "Widget";
244                 String controllerName = "Portal" + widgetId + "Ctrl";
245                 String cssName = "portal" + widgetId + "-css-ready";
246                 String colorArg1 = "color: #fff";
247                 String framework = sb.replaceAll("ARUGMENT1", namespace).replaceAll("ARUGMENT2", controllerName)
248                                 .replaceAll("ARUGMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
249                                 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
250                                 .replaceAll("WIDGET_ID", Long.toString(widgetId));
251
252                 widgetFile.setFramework(framework.getBytes());
253
254                 final byte[] controllerLoc = map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION);
255                 if (controllerLoc == null || controllerLoc.length == 0)
256                         throw new IllegalArgumentException(
257                                         "Map is missing required key " + WidgetConstant.WIDGET_CONTROLLER_LOCATION);
258                 String javascript = new String(controllerLoc);
259                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
260                 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
261                 javascript = javascript.replaceFirst(functionName, controllerName);
262                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
263                 List<String> paramList = Arrays.asList(functionParam.split(","));
264
265                 int left_bracket_index = javascript.indexOf("{") + 1;
266                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
267                 javascript = javascript.substring(0, left_bracket_index) + widgetData
268                                 + javascript.substring(left_bracket_index);
269
270                 StringBuilder injectStr = new StringBuilder().append("[");
271                 for (int i = 0; i < paramList.size(); i++) {
272                         if (i == paramList.size() - 1)
273                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
274                         else
275                                 injectStr.append("'" + paramList.get(i).trim() + "',");
276                 }
277                 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
278                                 + injectStr.toString();
279
280                 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
281                                 controllerName);
282                 ;
283
284                 Pattern cssPattern = Pattern.compile("#.*-css-ready");
285                 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
286                 if (cssMatcher.find()) {
287                         widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
288                                         .replace(cssMatcher.group(0), "#" + cssName).getBytes());
289                 }
290
291                 widgetFile.setMarkup(html.getBytes());
292                 widgetFile.setController(javascript.getBytes());
293                 Session session = sessionFactory.openSession();
294                 session.save(widgetFile);
295                 session.flush();
296                 session.close();
297                 // sessionFactory.getCurrentSession().save(widgetFile);
298                 logger.debug(
299                                 "StorageServiceImpl.save: saved fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
300                                 widgetId);
301
302         }
303
304         @Override
305         public void update(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
306                 UnzipUtil unzipper = new UnzipUtil();
307                 Map<String, byte[]> map;
308                 File convFile;
309                 try {
310                         if (file.isEmpty()) {
311                                 logger.error("StorageServiceImpl.update: Failed to store empty file " + file.getOriginalFilename());
312                                 throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
313                         }
314                         String fileLocation = file.getOriginalFilename();
315                         logger.debug("StorageServiceImpl.update: store the widget to:" + fileLocation);
316                         convFile = new File(fileLocation);
317                         FileOutputStream fos = new FileOutputStream(convFile);
318                         fos.write(file.getBytes());
319                         fos.close();
320                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
321                         convFile.delete();
322                 } catch (IOException e) {
323                         logger.error("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(), e);
324                         throw new StorageException("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(),
325                                         e);
326                 }
327                 WidgetFile widgetFile = getWidgetFile(widgetId);
328
329                 InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js");
330                 String sb = null;
331                 try {
332                         byte[] bytes = new byte[fileInputStream.available()];
333                         fileInputStream.read(bytes);
334                         sb = new String(bytes, "UTF-8");
335                 } catch (IOException e) {
336                         logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
337                         e.printStackTrace();
338                 } finally {
339                         if (fileInputStream != null) {
340                                 try {
341                                         fileInputStream.close();
342                                 } catch (IOException e) {
343                                         logger.error("StorageServiceImpl.update: Failed to close the fileInputStream ", e);
344                                         e.printStackTrace();
345                                 }
346                         }
347                 }
348
349                 String namespace = "Portal" + widgetId + "Widget";
350                 String controllerName = "Portal" + widgetId + "Ctrl";
351                 String cssName = "portal" + widgetId + "-css-ready";
352                 String colorArg1 = "color: #fff";
353                 String framework = sb.replaceAll("ARUGMENT1", namespace).replaceAll("ARUGMENT2", controllerName)
354                                 .replaceAll("ARUGMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
355                                 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
356                                 .replaceAll("WIDGET_ID", Long.toString(widgetId));
357                 widgetFile.setFramework(framework.getBytes());
358
359                 String javascript = new String(map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION));
360                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
361                 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
362                 javascript = javascript.replaceFirst(functionName, controllerName);
363                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
364                 List<String> paramList = Arrays.asList(functionParam.split(","));
365
366                 int left_bracket_index = javascript.indexOf("{") + 1;
367                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
368                 javascript = javascript.substring(0, left_bracket_index) + widgetData
369                                 + javascript.substring(left_bracket_index);
370
371                 StringBuilder injectStr = new StringBuilder().append("[");
372                 for (int i = 0; i < paramList.size(); i++) {
373                         if (i == paramList.size() - 1)
374                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
375                         else
376                                 injectStr.append("'" + paramList.get(i).trim() + "',");
377                 }
378                 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
379                                 + injectStr.toString();
380
381                 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
382                                 controllerName);
383                 ;
384
385                 Pattern cssPattern = Pattern.compile("#.*-css-ready");
386                 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
387                 if (cssMatcher.find()) {
388                         widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
389                                         .replace(cssMatcher.group(0), "#" + cssName).getBytes());
390                 }
391
392                 widgetFile.setMarkup(html.getBytes());
393                 widgetFile.setController(javascript.getBytes());
394                 // widgetFile.setCss(map.get(WidgetConstant.WIDGET_STYLE_LOCATION));
395                 Session session = sessionFactory.openSession();
396                 Transaction tx = session.beginTransaction();
397                 session.update(widgetFile);
398                 tx.commit();
399                 session.flush();
400                 session.close();
401                 logger.debug(
402                                 "StorageServiceImpl.save: updated fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
403                                 widgetId);
404         }
405
406         @Override
407         @SuppressWarnings("unchecked")
408         @Transactional
409         public String getWidgetMarkup(long widgetId) throws UnsupportedEncodingException {
410                 String markup = null;
411                 Session session = sessionFactory.getCurrentSession();
412                 Criteria criteria = session.createCriteria(WidgetFile.class);
413                 criteria.add(Restrictions.eq("widgetId", widgetId));
414                 List<WidgetFile> widgetFile = criteria.list();
415                 logger.debug("StorageServiceImpl.getWidgetMarkup: getting widget markup result={}", widgetFile);
416
417                 if (widgetFile.size() > 0)
418                         markup = new String(widgetFile.get(0).getMarkup(), "UTF-8");
419                 return markup;
420         }
421
422         @Override
423         @SuppressWarnings("unchecked")
424         @Transactional
425         public String getWidgetController(long widgetId) throws UnsupportedEncodingException {
426                 String controller = null;
427                 Session session = sessionFactory.getCurrentSession();
428                 Criteria criteria = session.createCriteria(WidgetFile.class);
429                 criteria.add(Restrictions.eq("widgetId", widgetId));
430                 List<WidgetFile> widgetFile = criteria.list();
431                 logger.debug("StorageServiceImpl.getWidgetController: getting widget controller result={}", widgetFile);
432
433                 if (widgetFile.size() > 0)
434                         controller = new String(widgetFile.get(0).getController(), "UTF-8");
435                 return controller;
436         }
437
438         @Override
439         @SuppressWarnings("unchecked")
440         @Transactional
441         public String getWidgetFramework(long widgetId) throws UnsupportedEncodingException {
442                 String framework = null;
443                 Session session = sessionFactory.getCurrentSession();
444                 Criteria criteria = session.createCriteria(WidgetFile.class);
445                 criteria.add(Restrictions.eq("widgetId", widgetId));
446                 List<WidgetFile> widgetFile = criteria.list();
447                 logger.debug("StorageServiceImpl.getWidgetFramework: getting widget framework result={}", widgetFile);
448
449                 if (widgetFile.size() > 0)
450                         framework = new String(widgetFile.get(0).getFramework(), "UTF-8");
451                 return framework;
452         }
453
454         @Override
455         @SuppressWarnings("unchecked")
456         @Transactional
457         public String getWidgetCSS(long widgetId) throws UnsupportedEncodingException {
458                 String css = null;
459                 Session session = sessionFactory.getCurrentSession();
460                 Criteria criteria = session.createCriteria(WidgetFile.class);
461                 criteria.add(Restrictions.eq("widgetId", widgetId));
462                 List<WidgetFile> widgetFile = criteria.list();
463                 logger.debug("StorageServiceImpl.getWidgetCSS: getting widget css result={}", widgetFile);
464
465                 if (widgetFile.size() > 0)
466                         css = new String(widgetFile.get(0).getCss(), "UTF-8");
467                 return css;
468         }
469
470         @Override
471         @Transactional
472         public byte[] getWidgetCatalogContent(long widgetId) throws Exception {
473
474                 WidgetCatalog widget = widgetCatalogService.getWidgetCatalog(widgetId);
475                 String namespace = "Portal" + widgetId + "Widget";
476                 String controllerName = "Portal" + widgetId + "Ctrl";
477                 String cssName = "portal" + widgetId + "-css-ready";
478
479                 String styles = getWidgetCSS(widgetId).replaceAll(cssName, widget.getName() + "-css-ready");
480                 File f = File.createTempFile("temp", ".zip");
481                 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
482                 ZipEntry e = new ZipEntry(widget.getName() + "/styles/styles.css");
483                 out.putNextEntry(new ZipEntry(widget.getName() + "/"));
484                 out.putNextEntry(new ZipEntry(widget.getName() + "/styles/"));
485                 out.putNextEntry(e);
486                 byte[] data = styles.getBytes();
487                 out.write(data, 0, data.length);
488
489                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
490                 String javascript = getWidgetController(widgetId).replace(widgetData, "").replace(namespace + ".controller =",
491                                 "");
492
493                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
494                 javascript = javascript.replaceFirst(controllerName, widget.getName() + "Ctrl");
495                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
496                 StringBuilder injectStr = new StringBuilder().append("[");
497                 List<String> paramList = Arrays.asList(functionParam.split(","));
498                 for (int i = 0; i < paramList.size(); i++) {
499                         if (i == paramList.size() - 1)
500                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
501                         else
502                                 injectStr.append("'" + paramList.get(i).trim() + "',");
503                 }
504                 javascript = javascript.replace(";" + namespace + ".controller.$inject = " + injectStr.toString(), "");
505
506                 e = new ZipEntry(widget.getName() + "/js/controller.js");
507                 out.putNextEntry(new ZipEntry(widget.getName() + "/js/"));
508                 out.putNextEntry(e);
509                 data = javascript.getBytes();
510                 out.write(data, 0, data.length);
511
512                 String html = getWidgetMarkup(widgetId).replaceFirst(controllerName, widget.getName() + "Ctrl");
513
514                 // new
515                 // String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
516                 // controllerName);;
517
518                 e = new ZipEntry(widget.getName() + "/markup/markup.html");
519                 out.putNextEntry(new ZipEntry(widget.getName() + "/markup/"));
520                 out.putNextEntry(e);
521                 data = html.getBytes();
522                 out.write(data, 0, data.length);
523                 out.closeEntry();
524                 out.close();
525                 byte[] result = Files.readAllBytes(Paths.get(f.getPath()));
526                 f.delete();
527                 return result;
528         }
529
530 }