/* * DiagramAnalyser.java * * This file is part of the STS-Tool project. * Copyright (c) 2011-2012 "University of Trento - DISI" All rights reserved. * * Is strictly forbidden to remove this copyright notice from this source code. * * Disclaimer of Warranty: * STS-Tool (this software) is provided "as-is" and without warranty of any kind, * express, implied or otherwise, including without limitation, any warranty of * merchantability or fitness for a particular purpose. * In no event shall the copyright holder or contributors be liable for any direct, * indirect, incidental, special, exemplary, or consequential damages * including, but not limited to, procurement of substitute goods or services; * loss of use, data, or profits; or business interruption) however caused and on * any theory of liability, whether in contract, strict liability, or tort (including * negligence or otherwise) arising in any way out of the use of this software, even * if advised of the possibility of such damage. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License version 3 * as published by the Free Software Foundation with the addition of the * following permission added to Section 15 as permitted in Section 7(a): * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY * "University of Trento - DISI","University of Trento - DISI" DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * See the GNU Affero General Public License for more details. * You should have received a copy of the GNU Affero General Public License * along with this program; if not, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA, 02110-1301 USA, or download the license from the following URL: * http://www.sts-tool.eu/License.php * * For more information, please contact STS-Tool group at this * address: ststool@disi.unitn.it * */ package eu.aniketos.wp1.ststool.analysis.util.analyser; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import eu.aniketos.wp1.ststool.StsToolDiagram; import eu.aniketos.wp1.ststool.analysis.Activator; import eu.aniketos.wp1.ststool.analysis.results.IResult; import eu.aniketos.wp1.ststool.analysis.util.analyser.AbstractTask.TaskResult; import eu.aniketos.wp1.ststool.analysis.util.analyser.ITaskListener.InterruptionType; import eu.aniketos.wp1.ststool.analysis.util.analyser.internal.DiagramAnalyserThread; import eu.aniketos.wp1.ststool.diagram.part.StsToolDiagramEditor; public final class DiagramAnalyser { private List<ITaskListener> listeners = new ArrayList<ITaskListener>(); private Map<ITasksGroup, List<AbstractTask>> tasksGroupMap = new HashMap<ITasksGroup, List<AbstractTask>>(); public void addTaskGroupClass(Class<? extends ITasksGroup> clazz) throws InstantiationException,IllegalAccessException{ if (clazz.isInterface()) throw new RuntimeException("Invalid parameter class: Can't be an interface"); //$NON-NLS-1$ for (ITasksGroup taskGroup : tasksGroupMap.keySet()) { if (taskGroup.getClass().equals(clazz)) return; } ITasksGroup tasksGroup = clazz.newInstance(); addTaskGroup(tasksGroup); } public void addTaskGroup(ITasksGroup tasksGroup){ if (tasksGroupMap.containsKey(tasksGroup)) return; tasksGroupMap.put(tasksGroup, tasksGroup.getTasks()); } public void removeAllTaskGroups(){ tasksGroupMap.clear(); } protected List<AbstractTask> getAllTask(){ List<AbstractTask> result = new ArrayList<AbstractTask>(); for (List<AbstractTask> t : tasksGroupMap.values()) result.addAll(t); return result; } protected TaskResult performTask(AbstractTask task,StsToolDiagram diagram,List<IResult> analysisResults,boolean waitMinTime) throws Exception{ if (diagram == null) throw new AnalysisException("Invalid input parameter : diagram can't be null"); //$NON-NLS-1$ if (analysisResults == null) throw new AnalysisException("Invalid input parameter : analysisResults can't be null"); //$NON-NLS-1$ long startTime = System.currentTimeMillis(); TaskResult taskResult = task.executeTask(diagram, analysisResults); for (IResult r : analysisResults) { r.setTaskName(task.getName()); } long passedTime = System.currentTimeMillis() - startTime; int mintime = task.getMinTime(); if (waitMinTime && passedTime < mintime) { try { Thread.sleep(mintime - passedTime); } catch (InterruptedException e) { e.printStackTrace(); } } fireTaskCompelte(task, taskResult, analysisResults); return taskResult; } protected boolean performTasks(List<AbstractTask> tasks,StsToolDiagram diagram,boolean sort,final Map<AbstractTask, List<IResult>> resultMap){ return performTasks(tasks, diagram, sort, resultMap, new NullProgressMonitor()); } /** * /** Execute a list of Task; * * @param tasks * @param diagram * @param sort * Task is sorted by AnalysisTasksProvider.priority -> AnalysisTasksProvider -> task.priority -> task.name * @param monitor * @return */ protected boolean performTasks(List<AbstractTask> tasks,StsToolDiagram diagram,boolean sort,final Map<AbstractTask, List<IResult>> resultMap,IProgressMonitor monitor){ if (diagram == null) throw new AnalysisException("Invalid input parameter : diagram can't be null"); //$NON-NLS-1$ if (tasks == null) throw new AnalysisException("Invalid input parameter : tasks can't be null"); //$NON-NLS-1$ final boolean isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString().indexOf("-agentlib:jdwp") > 0; //$NON-NLS-1$ if (sort) { /** * Sort by AnalysisTasksProvider.priority -> AnalysisTasksProvider -> task.priority -> task.name */ tasks = new ArrayList<AbstractTask>(tasks); Collections.sort(tasks); } boolean returnValue = true; try { if (tasks != null && tasks.size() > 0) { int tickets = 100; int checkTiket = tickets / tasks.size(); monitor.beginTask("Starting Analysis", tickets); //$NON-NLS-1$ final Set<ITasksGroup> tasksGroupToSkip = new HashSet<ITasksGroup>(); boolean skipAll = false; for (int i = 0; i < tasks.size(); i++) { AbstractTask currentTask = tasks.get(i); monitor.setTaskName(currentTask.getGroup().getGroupName()); monitor.subTask(currentTask.getName()); if (tasksGroupToSkip.contains(currentTask.getGroup()) || skipAll || monitor.isCanceled()) { fireTaskSkipped(currentTask); Thread.sleep(40); } else { List<IResult> analysisResults = new ArrayList<IResult>(); DiagramAnalyserThread t = new DiagramAnalyserThread(this, currentTask, diagram, analysisResults); t.start(); fireTaskStarted(currentTask); int timeout = currentTask.getTimeOut(); long time = System.currentTimeMillis(); InterruptionType intType = null; while (!t.isTerminated()) { if (monitor.isCanceled()) { intType = InterruptionType.MONITOR_CANCELLED; } else if (timeout > 0 && System.currentTimeMillis() - time > timeout) { if (!isDebug) { intType = InterruptionType.TIMEOUT; } } if (intType != null) { t.stop(); returnValue = false; } else { Thread.sleep(1); } } if (intType == null && !t.isTerminatedNormally()) { intType = InterruptionType.EXCEPTION; String logString = "Exception occured during analysis - Task: \"" + currentTask.getName() + "\" : " + t.getException().getMessage(); //$NON-NLS-1$ //$NON-NLS-2$ Activator.getDefault().getLog().log(new Status(Status.ERROR, Activator.PLUGIN_ID, logString, t.getException())); returnValue = false; } if (intType != null) { if (intType == InterruptionType.EXCEPTION) { fireTaskInterrupted(currentTask, intType, t.getException()); } else { fireTaskInterrupted(currentTask, intType, null); } if (intType != InterruptionType.MONITOR_CANCELLED) { switch (currentTask.getBlockType()) { case CLASS: tasksGroupToSkip.add(currentTask.getGroup()); break; case ANALYSIS: monitor.setCanceled(true); break; } } } else { if (t.getResult() == TaskResult.COMPLETED_ERROR) { returnValue = false; switch (currentTask.getBlockType()) { case CLASS: tasksGroupToSkip.add(currentTask.getGroup()); break; case ANALYSIS: skipAll = true; break; } } else { resultMap.put(currentTask, analysisResults); } } } monitor.worked(checkTiket); } } } catch (Exception e) { throw new AnalysisException("Exception occurred while performing task :" + e.getMessage(), e); //$NON-NLS-1$ } finally { if (monitor != null) monitor.done(); } return returnValue; } public boolean evaluateCurrentDiagram() throws AnalysisException{ return evaluateCurrentDiagram(null, null); } public boolean evaluateCurrentDiagram(Map<ITasksGroup, List<IResult>> resultsMap) throws AnalysisException{ return evaluateCurrentDiagram(resultsMap, null); } private StsToolDiagram diagram; @SuppressWarnings("static-access") public boolean evaluateCurrentDiagram(Map<ITasksGroup, List<IResult>> resultsMap,IProgressMonitor monitor) throws AnalysisException{ if (monitor == null) monitor = new NullProgressMonitor(); final IWorkbench workbench = PlatformUI.getWorkbench(); if (workbench.getDisplay().getCurrent() == null) { workbench.getDisplay().syncExec(new Runnable() { @Override public void run(){ IEditorPart editor = workbench.getActiveWorkbenchWindow().getActivePage().getActiveEditor(); if (editor instanceof StsToolDiagramEditor) diagram = ((StsToolDiagramEditor) editor).getStsModel(); } }); } else { IEditorPart editor = workbench.getActiveWorkbenchWindow().getActivePage().getActiveEditor(); if (editor instanceof StsToolDiagramEditor) diagram = ((StsToolDiagramEditor) editor).getStsModel(); } if (diagram == null) { throw new AnalysisException("No active diagram found"); } //$NON-NLS-1$ return evaluateDiagram(diagram, resultsMap, monitor); } public boolean evaluateDiagram(StsToolDiagram diagram,Map<ITasksGroup, List<IResult>> resultsMap,IProgressMonitor monitor){ try { Map<AbstractTask, List<IResult>> res = new HashMap<AbstractTask, List<IResult>>(); boolean result = performTasks(getAllTask(), diagram, true, res, monitor); if (resultsMap != null) { for (AbstractTask task : res.keySet()) { if (resultsMap.containsKey(task.getGroup())) { List<IResult> x = resultsMap.get(task.getGroup()); x.addAll(res.get(task)); resultsMap.put(task.getGroup(), x); } else { resultsMap.put(task.getGroup(), res.get(task)); } } } return result; } catch (Exception e) { throw new AnalysisException("Error encountred during analysis :" + e.getMessage(), e); //$NON-NLS-1$ } finally { if (monitor != null) monitor.done(); } } public void addTaskListener(ITaskListener listener){ listeners.add(listener); } public void removeTaskListener(ITaskListener listener){ listeners.remove(listener); } protected void fireTaskStarted(AbstractTask task){ for (ITaskListener l : listeners) { l.taskStarted(task); } } protected void fireTaskCompelte(AbstractTask task,TaskResult taskResult,List<IResult> analysisResult){ for (ITaskListener l : listeners) { l.taskCompleted(task, taskResult, analysisResult); } } protected void fireTaskSkipped(AbstractTask task){ for (ITaskListener l : listeners) { l.taskSkipped(task); } } protected void fireTaskInterrupted(AbstractTask task,InterruptionType userInterrupt,Throwable ex){ for (ITaskListener l : listeners) { l.taskInterrupted(task, userInterrupt, ex); } } }