2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * ===================================================================
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
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
26 * https://creativecommons.org/licenses/by/4.0/
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.
34 * ============LICENSE_END============================================
36 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
38 package org.openecomp.portalapp.widget.service.impl;
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;
50 import java.util.regex.Matcher;
51 import java.util.regex.Pattern;
52 import java.util.zip.ZipEntry;
53 import java.util.zip.ZipOutputStream;
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;
76 public class StorageServiceImpl implements StorageService {
78 private static final Logger logger = LoggerFactory.getLogger(StorageServiceImpl.class);
81 private SessionFactory sessionFactory;
84 WidgetCatalogService widgetCatalogService;
88 public void deleteWidgetFile(long widgetId) {
89 WidgetFile widgetFile = getWidgetFile(widgetId);
90 logger.debug("StorageServiceImpl.deleteWidgetFile: deleting widget file {}", widgetId);
91 if (widgetFile == null) {
93 "StorageServiceImpl.deleteWidgetFile: No widget file found in database while performing StorageServiceImpl.deleteWidgetFile.");
96 Session session = sessionFactory.getCurrentSession();
97 Transaction tx = session.beginTransaction();
98 session.delete(widgetFile);
103 @SuppressWarnings("unchecked")
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();
114 if (widgetFiles.size() > 0)
115 widgetFile = widgetFiles.get(0);
120 public ValidationRespond checkZipFile(MultipartFile file) {
121 StringBuilder error_msg = new StringBuilder();
122 UnzipUtil unzipper = new UnzipUtil();
123 Map<String, byte[]> map;
125 boolean isValid = true;
126 if (!file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')).equals(".zip")) {
128 error_msg.append(WidgetConstant.VALIDATION_MESSAGE_ZIP);
129 logger.error("StorageServiceImpl.checkZipFile: invalid file format");
132 if (file.isEmpty()) {
134 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
135 throw new StorageException(
136 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
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());
144 map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
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);
152 for (byte[] b : map.values()) {
153 if (isValid && b == null) {
155 error_msg.append(WidgetConstant.VALIDATION_MESSAGE_FILES);
159 return new ValidationRespond(isValid, error_msg.toString());
164 public void save(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
166 UnzipUtil unzipper = new UnzipUtil();
167 Map<String, byte[]> map;
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());
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());
180 map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
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);
186 saveHelper(newWidget, widgetId, map);
191 public void initSave(File file, WidgetCatalog newWidget, long widgetId) {
193 UnzipUtil unzipper = new UnzipUtil();
194 Map<String, byte[]> map;
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);
205 saveHelper(newWidget, widgetId, map);
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
216 private void saveHelper(WidgetCatalog newWidget, long widgetId, Map<String, byte[]> map) {
218 logger.debug("Going to save widget " + newWidget);
219 WidgetFile widgetFile = new WidgetFile();
220 widgetFile.setName(newWidget.getName());
221 widgetFile.setWidgetId(widgetId);
223 InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js");
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);
234 if (fileInputStream != null) {
236 fileInputStream.close();
237 } catch (IOException e) {
238 logger.error("StorageServiceImpl.update: Failed to close the fileInputStream ", e);
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("ARGUMENT1", namespace).replaceAll("ARGUMENT2", controllerName)
248 .replaceAll("ARGUMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
249 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
250 .replaceAll("WIDGET_ID", Long.toString(widgetId));
252 widgetFile.setFramework(framework.getBytes());
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(","));
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);
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() + "'];");
275 injectStr.append("'" + paramList.get(i).trim() + "',");
277 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
278 + injectStr.toString();
280 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
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());
291 widgetFile.setMarkup(html.getBytes());
292 widgetFile.setController(javascript.getBytes());
293 Session session = sessionFactory.openSession();
294 session.save(widgetFile);
297 // sessionFactory.getCurrentSession().save(widgetFile);
299 "StorageServiceImpl.save: saved fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
305 public void update(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
306 UnzipUtil unzipper = new UnzipUtil();
307 Map<String, byte[]> map;
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());
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());
320 map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
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(),
327 WidgetFile widgetFile = getWidgetFile(widgetId);
329 InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js");
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);
339 if (fileInputStream != null) {
341 fileInputStream.close();
342 } catch (IOException e) {
343 logger.error("StorageServiceImpl.update: Failed to close the fileInputStream ", e);
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("ARGUMENT1", namespace).replaceAll("ARGUMENT2", controllerName)
354 .replaceAll("ARGUMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
355 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
356 .replaceAll("WIDGET_ID", Long.toString(widgetId));
357 widgetFile.setFramework(framework.getBytes());
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(","));
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);
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() + "'];");
376 injectStr.append("'" + paramList.get(i).trim() + "',");
378 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
379 + injectStr.toString();
381 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
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());
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);
402 "StorageServiceImpl.save: updated fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
407 @SuppressWarnings("unchecked")
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);
417 if (widgetFile.size() > 0)
418 markup = new String(widgetFile.get(0).getMarkup(), "UTF-8");
423 @SuppressWarnings("unchecked")
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);
433 if (widgetFile.size() > 0)
434 controller = new String(widgetFile.get(0).getController(), "UTF-8");
439 @SuppressWarnings("unchecked")
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);
449 if (widgetFile.size() > 0)
450 framework = new String(widgetFile.get(0).getFramework(), "UTF-8");
455 @SuppressWarnings("unchecked")
457 public String getWidgetCSS(long widgetId) throws UnsupportedEncodingException {
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);
465 if (widgetFile.size() > 0)
466 css = new String(widgetFile.get(0).getCss(), "UTF-8");
472 public byte[] getWidgetCatalogContent(long widgetId) throws Exception {
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";
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/"));
486 byte[] data = styles.getBytes();
487 out.write(data, 0, data.length);
489 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
490 String javascript = getWidgetController(widgetId).replace(widgetData, "").replace(namespace + ".controller =",
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() + "'];");
502 injectStr.append("'" + paramList.get(i).trim() + "',");
504 javascript = javascript.replace(";" + namespace + ".controller.$inject = " + injectStr.toString(), "");
506 e = new ZipEntry(widget.getName() + "/js/controller.js");
507 out.putNextEntry(new ZipEntry(widget.getName() + "/js/"));
509 data = javascript.getBytes();
510 out.write(data, 0, data.length);
512 String html = getWidgetMarkup(widgetId).replaceFirst(controllerName, widget.getName() + "Ctrl");
515 // String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
518 e = new ZipEntry(widget.getName() + "/markup/markup.html");
519 out.putNextEntry(new ZipEntry(widget.getName() + "/markup/"));
521 data = html.getBytes();
522 out.write(data, 0, data.length);
525 byte[] result = Files.readAllBytes(Paths.get(f.getPath()));