/* CloudTrail Viewer, is a Java desktop application for reading AWS CloudTrail logs files. Copyright (C) 2017 Mark P. Haskins This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package io.haskins.java.cloudtrailviewer.controller.widget; import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon; import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView; import io.haskins.java.cloudtrailviewer.model.DashboardWidget; import io.haskins.java.cloudtrailviewer.model.event.Event; import io.haskins.java.cloudtrailviewer.service.DatabaseService; import io.haskins.java.cloudtrailviewer.service.EventTableService; import io.haskins.java.cloudtrailviewer.utils.FileUtils; import javafx.concurrent.Worker; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.layout.BorderPane; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.events.EventTarget; import java.io.*; import java.util.List; import java.util.Map; import java.util.logging.Level; /** * Controller class that provides a Map widget * * Created by markhaskins on 10/01/2017. */ public class MapWidgetController extends AbstractBaseController { private static final String HTML_FILENAME = "geoData.html"; @FXML private WebView map; private WebEngine webEngine; @FXML private void initialize() { webEngine = map.getEngine(); webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> { if (newValue == Worker.State.SUCCEEDED) { Document doc = webEngine.getDocument(); NodeList nList = doc.getElementsByTagName("Div"); for (int i=0; i < nList.getLength(); i++) { Node node = nList.item(i); Element element = (Element) node; if (element.getAttribute("class") != null && element.getAttribute("class").equalsIgnoreCase("city")) { ((EventTarget) element).addEventListener( "click", ev -> { String cityName = element.getTextContent(); eventTableService.setTableEvents(keyValueMap.get(cityName)); }, false ); } } } }); } public BorderPane loadFXML() { FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/widget/MapWidget.fxml")); loader.setController(this); try { fxmlObject = loader.load(); } catch (IOException e) { e.printStackTrace(); } return fxmlObject; } FontAwesomeIconView getWidgetIcon() { return new FontAwesomeIconView(FontAwesomeIcon.MAP_MARKER); } @Override public void configure(DashboardWidget widget, EventTableService eventTableService, DatabaseService databaseService) { super.configure(widget, eventTableService, databaseService); map.setPrefHeight(widget.getHeight()); map.setPrefWidth(widget.getWidth()); widgetControlsController.hideEditButton(); } public void newEvents(List<Event> events) { for (Event event : events) { newEvent(event); } } public void loadingFile(int fileName, int totalFiles) { } public void finishedLoading(boolean reload) { StringBuilder output = new StringBuilder(); int highestCount = 0; String centerPoint = ""; for (Map.Entry<String, String> entry : latlngs.entrySet()) { List<Event> events = keyValueMap.get(entry.getValue()); output.append("['"). append(entry.getValue()). append(":"). append(events.size()). append("',"). append(entry.getKey()). append("]"); output.append(","); String cityName = entry.getValue(); if (cityName != null && cityName.trim().length() > 0) { int totalEvents = events.size(); if (totalEvents > highestCount) { centerPoint = entry.getKey(); highestCount = totalEvents; } } } String html = getHTML(); html = html.replaceAll("COORDS", output.toString()); html = html.replaceAll("CENTER", centerPoint); writeGeoDataHtml(html); webEngine.load("file://" + FileUtils.getFullPathToFile(HTML_FILENAME)); } private String getHTML() { StringBuilder result = new StringBuilder(); ClassLoader classLoader = this.getClass().getClassLoader(); InputStreamReader io = new InputStreamReader(classLoader.getResourceAsStream("geodata/GeoIp.html")); try( BufferedReader br = new BufferedReader(io) ) { String line; while ((line = br.readLine()) != null) { result.append(line).append("\n"); } } catch (IOException ioe) { LOGGER.log(Level.WARNING, "Unable to load service APIs", ioe); } return result.toString(); } private void writeGeoDataHtml(String htmtContent) { try { File f = new File(FileUtils.getFullPathToFile(HTML_FILENAME)); if (!f.delete()) { LOGGER.log(Level.WARNING, "Failed to delete existing Geo HTML file"); } } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to delete existing Geo HTML file", e); } FileUtils.writeStringToFile(htmtContent, FileUtils.getFullPathToFile(HTML_FILENAME)); try (BufferedWriter out = new BufferedWriter(new FileWriter(FileUtils.getFullPathToFile(HTML_FILENAME)))) { out.write(htmtContent); out.close(); } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to create new Geo HTML file", e); } } }