/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * HUMBOLDT EU Integrated Project #030962 * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.ui.service.report.internal; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArraySet; import org.eclipse.core.runtime.Platform; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import com.google.common.collect.Multimap; import de.fhg.igd.slf4jplus.ALogger; import de.fhg.igd.slf4jplus.ALoggerFactory; import eu.esdihumboldt.hale.common.core.report.Message; import eu.esdihumboldt.hale.common.core.report.Report; import eu.esdihumboldt.hale.common.core.report.ReportSession; import eu.esdihumboldt.hale.common.core.report.writer.ReportReader; import eu.esdihumboldt.hale.common.core.report.writer.ReportWriter; import eu.esdihumboldt.hale.ui.service.report.ReportListener; import eu.esdihumboldt.hale.ui.service.report.ReportService; /** * Report service implementation * * @author Simon Templer * @partner 01 / Fraunhofer Institute for Computer Graphics Research * @since 2.2 */ public class ReportServiceImpl implements ReportService { private final CopyOnWriteArraySet<ReportListener<?, ?>> listeners = new CopyOnWriteArraySet<ReportListener<?, ?>>(); /** * Map containing {@link ReportSession}s. */ private final Map<Long, ReportSession> reps = new HashMap<Long, ReportSession>(); /** * Contains the current session description. */ private long description = 0; private static final ALogger _log = ALoggerFactory.getLogger(ReportService.class); private ReportSession getCurrentSession() { // check if a current session exists if (this.getCurrentSessionDescription() == 0) { this.updateCurrentSessionDescription(); } long time = this.description; ReportSession session = reps.get(time); if (session == null) { session = new ReportSession(time); reps.put(time, session); } return session; } /** * @see ReportService#addReport(Report) */ @SuppressWarnings("unchecked") @Override public <M extends Message, R extends Report<M>> void addReport(R report) { ReportSession session = this.getCurrentSession(); session.addReport(report); // open ReportList openView(); // notify listeners notifyReportAdded(report.getClass(), report.getMessageType(), report); } /** * Notify listeners that a report has been added * * @param <M> the message type * @param <R> the report type * * @param reportType the report type * @param messageType the message type * @param report the report */ @SuppressWarnings("unchecked") protected <M extends Message, R extends Report<M>> void notifyReportAdded( Class<? extends R> reportType, Class<M> messageType, R report) { for (ReportListener<?, ?> listener : listeners) { if (listener.getReportType().isAssignableFrom(reportType) && listener.getMessageType().isAssignableFrom(messageType)) { ((ReportListener<R, M>) listener).reportAdded(report); } } } /** * Notify listeners that all reports have been deleted */ protected void notifyReportsDeleted() { for (ReportListener<?, ?> listener : listeners) { listener.reportsDeleted(); } } /** * Open the ReportList view. */ private void openView() { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @Override public void run() { try { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); if (window == null) { if (windows.length > 0) { window = windows[0]; } else { /* * we have no active window and no other window... * so we better exit here */ _log.error("Could not open report view! No window available."); return; } } IWorkbenchPage page = window.getActivePage(); page.showView("eu.esdihumboldt.hale.ui.views.report.ReportList"); } catch (Exception e) { _log.error("Could not open report view!", e); } } }); } /** * Get all reports matching the given message type * * @param messageType the message type * @return report types mapped to reports */ @Override public Multimap<Class<? extends Report<?>>, Report<?>> getReports( Class<? extends Message> messageType) { return this.getCurrentSession().getReports(messageType); } /** * Get all reports. * * @return all reports */ @Override public Multimap<Class<? extends Report<?>>, Report<?>> getCurrentReports() { return this.getCurrentSession().getAllReports(); } /** * @see ReportService#addReportListener(ReportListener) */ @Override public void addReportListener(ReportListener<?, ?> listener) { listeners.add(listener); } /** * @see ReportService#removeReportListener(ReportListener) */ @Override public void removeReportListener(ReportListener<?, ?> listener) { listeners.remove(listener); } /** * @see eu.esdihumboldt.hale.ui.service.report.ReportService#deleteAllReports() */ @Override public void deleteAllReports() { // clear the list this.reps.clear(); // clear storage folder File folder = new File(Platform.getLocation().toString() + "/reports/"); if (folder.exists()) { for (File f : folder.listFiles()) { if (!f.delete()) { _log.error("Could not delete file: " + f.toString()); } } if (!folder.delete()) { _log.error("Could not delete saved reports."); } } // notify listeners this.notifyReportsDeleted(); } /** * @see ReportService#saveCurrentReports(File) */ @Override public boolean saveCurrentReports(File file) throws IOException { return ReportWriter.write(file, this.getCurrentReports().values(), false); } /** * @see eu.esdihumboldt.hale.ui.service.report.ReportService#loadReportsOnStartup() */ @Override public void loadReportsOnStartup() { // folder where the reports shall be stored File folder = new File(Platform.getLocation().toString() + "/reports/"); // create a ReportReader ReportReader rr = new ReportReader(); // read all sessions from log folder List<ReportSession> list = rr.readDirectory(folder); // add them to internal storage for (ReportSession s : list) { this.reps.put(s.getId(), s); } } /** * @see eu.esdihumboldt.hale.ui.service.report.ReportService#saveReportsOnShutdown() */ @Override public void saveReportsOnShutdown() { // folder where the reports shall be stored File folder = new File(Platform.getLocation().toString() + "/reports/"); if (!folder.exists() && !folder.mkdirs()) { // folder does not exist and we cannot create it... _log.error("Folder for reports does not exist and cannot be created!"); return; } // iterate through all sessions for (ReportSession s : this.reps.values()) { SimpleDateFormat df = new SimpleDateFormat("yyyy_MM_dd_HH_mm"); File file = new File(folder.getPath() + "/" + df.format(new Date(s.getId())) + "-" + s.getId() + ".log"); try { ReportWriter.write(file, s.getAllReports().values(), false); } catch (IOException e) { // error during saving _log.error("Cannot save report session.", e); } } } /** * @see eu.esdihumboldt.hale.ui.service.report.ReportService#getAllSessions() */ @Override public Collection<ReportSession> getAllSessions() { return this.reps.values(); } /** * @see eu.esdihumboldt.hale.ui.service.report.ReportService#loadReport(java.io.File) */ @Override public void loadReport(File file) throws org.eclipse.jface.bindings.keys.ParseException { // create a ReportReader ReportReader rr = new ReportReader(); // read all sessions from log folder ReportSession s = rr.readFile(file); if (s == null) { throw new org.eclipse.jface.bindings.keys.ParseException("Log could not be read."); } // add them to internal storage this.reps.put(s.getId(), s); } /** * @see eu.esdihumboldt.hale.ui.service.report.ReportService#getCurrentSessionDescription() */ @Override public long getCurrentSessionDescription() { return this.description; } /** * @see eu.esdihumboldt.hale.ui.service.report.ReportService#updateCurrentSessionDescription() */ @Override public void updateCurrentSessionDescription() { // only update if the time differs for 5000ms if (this.description + 5000 < System.currentTimeMillis()) { this.description = System.currentTimeMillis(); } } }