Merge branch '253-review-checkers-execution' into 'master'

Resolve "Review checkers execution"

Closes #253

See merge request CPS_Design/CHESS!61
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/Checker.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/Checker.java
index 6b0973d..efd6208 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/Checker.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/Checker.java
@@ -13,9 +13,12 @@
 import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
 import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
 
+import org.eclipse.uml2.uml.Package;
+
 public abstract class Checker {
 
 	private static final Logger logger = Logger.getLogger(Checker.class);
+	public static String FAMILY = "checkers";
 
 //	private static String pluginID = "org.polarsys.chess.checkers";
 
@@ -44,13 +47,11 @@
 	public abstract void init() throws Exception;
 
 	public void asyncCheck(boolean isFirstChecker) throws Exception {
-		
 		CheckerManager checkerManager = org.polarsys.chess.checkers.Activator.getCheckerManager();
-		
 		org.eclipse.uml2.uml.Package pack = EntityUtil.getInstance().getCurrentSystemView();
-		if(pack==null){
+		if(pack == null) {
 			IFile file = EntityUtil.getInstance().getCurrentIFile();
-			System.out.println("file: "+file);
+			logger.debug("file: "+file);
 			EntityUtil.getInstance().openCurrentModelIntoEditor(file);			
 		}
 		
@@ -87,6 +88,55 @@
 		job.schedule();
 	}
 	
+	/**
+	 * Just runs the check() method and returns the scheduled job.
+	 * @param pack
+	 * @return
+	 */
+	public Job syncCheck(Package pack) {
+		CheckerManager checkerManager = org.polarsys.chess.checkers.Activator.getCheckerManager();
+		IFile iFile = WorkspaceSynchronizer.getFile(pack.eResource());
+
+		logger.debug("running checker: " + unifiedName);
+		Job job = new Job("Checker Manager: " + unifiedName) {
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				try {
+					errors = new ArrayList<Exception>();
+					List<CheckerMessage> messages = check(monitor);
+					checkerManager.updateCheckerStatus(unifiedName, true);
+					if (messages != null) {
+						checkerManager.deleteProjectMarkers(iFile.getProject(), unifiedName);
+						checkerManager.addMessages(unifiedName, messages);
+					}
+				} catch (Exception e) {
+					checkerManager.updateCheckerStatus(unifiedName, true);
+					e.printStackTrace();
+					logger.error("Checker '" + unifiedName + "' exception: " + e.getMessage());
+					return Status.CANCEL_STATUS;
+				}
+				if (monitor.isCanceled()) {
+					checkerManager.updateCheckerStatus(unifiedName, true);
+					logger.warn("checker '" + unifiedName + "' isCanceled");
+					return Status.CANCEL_STATUS;
+				}
+				// use this to open a Shell in the UI thread
+				return Status.OK_STATUS;
+			}
+			
+			@Override
+			public boolean belongsTo(Object family) {
+				if (Checker.FAMILY.equals(family)) {
+					return true;
+				} else {
+					return false;
+				}
+			}
+		};
+		job.schedule();
+		return job;
+	}
+	
 //	/**
 //	 * Recursively returns all the files in the given container
 //	 * @param container the IContainer
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerManager.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerManager.java
index c7184e3..40aba6d 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerManager.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerManager.java
@@ -5,13 +5,15 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-
 import org.apache.log4j.Logger;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.EValidator;
 import org.eclipse.emf.ecore.util.EcoreUtil;
@@ -26,6 +28,7 @@
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.part.IPage;
 import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Package;
 import org.eclipse.xtext.nodemodel.INode;
 import org.polarsys.chess.service.gui.utils.ReportProblemsUtil;
 
@@ -61,6 +64,52 @@
 		}
 	}
 
+	/**
+	 * Launches the init() of the various checkerContainers.
+	 * @param selectedCheckersTags
+	 * @throws Exception
+	 */
+	public void initSync(Set<String> selectedCheckersTags) throws Exception {
+		logger.debug("initSync");
+		for (CheckersContainer checkersContainer : checkersContainers) {
+			logger.debug("init checkersContainer");
+			checkersContainer.initSync(selectedCheckersTags);
+		}
+	}
+
+	/**
+	 * Launches the check() of the various checkerContainers and waits for their finish.
+	 * @param selectedCheckersTags
+	 * @param pkg
+	 * @return 
+	 */
+	public List<Exception> checkSync(Set<String> selectedCheckersTags, Package pkg, IProgressMonitor monitor) {
+		logger.debug("runSync");
+		final List<Exception> errors = new ArrayList<Exception>();
+		checkerStatus = new HashMap<String, Boolean>();
+		messages = new ArrayList<CheckerMessage>();
+		final List<Job> jobs = new ArrayList<Job>();
+		
+		// Start all the checks()
+		for (CheckersContainer checkersContainer : checkersContainers) {
+			logger.debug("run checkersContainer");
+			jobs.addAll(checkersContainer.checkSync(selectedCheckersTags, pkg));
+		}
+		
+		// Wait for the checks to finish
+		try {
+			Job.getJobManager().join(Checker.FAMILY, monitor);
+		} catch (OperationCanceledException | InterruptedException e1) {
+			logger.debug("Checker execution interrupted");
+			for (Job job : jobs) {
+				job.cancel();
+			}
+			errors.add(new Exception("Esecuzione checker interrotta"));
+			e1.printStackTrace();
+		}
+		return errors;
+	}
+	
 	public void register(CheckersContainer checkersContainer) {
 		logger.debug("register CheckersContainer");
 		this.checkersContainers.add(checkersContainer);
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckersContainer.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckersContainer.java
index 89ea553..05007a9 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckersContainer.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckersContainer.java
@@ -8,6 +8,8 @@
 import java.util.Set;
 
 import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.uml2.uml.Package;
 
 public class CheckersContainer {
 
@@ -23,20 +25,47 @@
 	}
 
 	public void run(Set<String> checkersTags) throws Exception {
-
 		boolean isFirstChecker = true;
-		
+
 		for (Checker checker : checkers) {
-
 			checkerManager.updateCheckerStatus(checker.unifiedName, false);
-
 			if (checker.belongsTo(checkersTags)) {
 				logger.debug("run " + checker.getUnifiedName());
-					checker.asyncCheck(isFirstChecker);
-					isFirstChecker=false;
+				checker.asyncCheck(isFirstChecker);
+				isFirstChecker=false;
 			}
 		}
+	}
 
+	/**
+	 * Runs the init() of the selected checkers.
+	 * @param checkersTags
+	 * @throws Exception
+	 */
+	public void initSync(Set<String> checkersTags) throws Exception {
+		for (Checker checker : checkers) {
+			if (checker.belongsTo(checkersTags)) {
+				logger.debug("init " + checker.getUnifiedName());
+				checker.init();
+			}
+		}
+	}
+
+	/**
+	 * Runs the check() of the selected checkers and returns the scheduled jobs.
+	 * @param checkersTags
+	 * @return the list of scheduled jobs 
+	 */
+	public List<Job> checkSync(Set<String> checkersTags, Package pkg) {
+		final List<Job> jobs = new ArrayList<Job>();
+		for (Checker checker : checkers) {
+			checkerManager.updateCheckerStatus(checker.unifiedName, false);
+			if (checker.belongsTo(checkersTags)) {
+				logger.debug("run " + checker.getUnifiedName());
+				jobs.add(checker.syncCheck(pkg));
+			}
+		}
+		return jobs;
 	}
 
 	public void register(Checker checker) {