/* * VTaskImpl.java * * Created on July 24, 2003, 5:08 PM */ package org.jboss.tools.common.verification.vrules.impl; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.SafeRunner; import org.jboss.tools.common.verification.vrules.VAction; import org.jboss.tools.common.verification.vrules.VEntity; import org.jboss.tools.common.verification.vrules.VHelper; import org.jboss.tools.common.verification.vrules.VManager; import org.jboss.tools.common.verification.vrules.VObject; import org.jboss.tools.common.verification.vrules.VResult; import org.jboss.tools.common.verification.vrules.VRule; import org.jboss.tools.common.verification.vrules.VTask; import org.jboss.tools.common.verification.vrules.VTaskListener; import org.jboss.tools.common.verification.vrules.plugin.VerificationPlugin; /** * * @author valera */ public class VTaskImpl implements VTask, Runnable { private VObject object; private VRule[] rules; private int index = 0; private List<VTaskListener> listeners = new ArrayList<VTaskListener>(); private Thread thread; private boolean running = false; private boolean sleeping = false; /** Creates a new instance of VTaskImpl */ public VTaskImpl(VManager manager, VObject object) { this.object = object; this.rules = VHelper.getRules(manager, object); } public VTaskImpl(VObject object, VRule[] rules) { this.object = object; this.rules = rules; } public void start() { if (thread == null) { thread = new Thread(this, "VTask"); //$NON-NLS-1$ thread.start(); } else { if(sleeping) { synchronized(this) { sleeping = false; try { notifyAll(); } catch (IllegalMonitorStateException e) { //ignore } } } } } public boolean isSleeping() { return sleeping; } public boolean isRunning() { return running; } public synchronized void pause() { if(running && !sleeping) sleeping = true; } public void stop() { sleeping = false; running = false; } public void run() { notifyStarted(); if(rules != null) for (index = 0; index < rules.length; index++) { if (!running) break; VRule rule = rules[index]; if (rule.isEnabled() && rule.getAction() != null && rule.getRuleSet().isEnabled()) { apply(rule, object); } notifyRuleFinished(rule, object); } notifyFinish(); } private void checkSleeping() { if(sleeping) { synchronized(this) { if(sleeping) { notifyPause(); try { wait(); } catch (InterruptedException e) { //ignore } if(!sleeping) notifyResume(); } } } } private void apply(VRule rule, VObject object) { VEntity entity = object.getEntity(); VEntity[] entities = rule.getEntities(); boolean checkChildren = false; boolean checked = false; for (int i = 0; i < entities.length; i++) { if(!running) return; checkSleeping(); if(!running) return; if (entity != null && entities[i] != null && entity.getName().equals(entities[i].getName())) { VAction action = rule.getAction(); if (action == null) { continue;// should not happen } VResult[] results = action.check(object); notifyApplied(rule, object, results); checked = true; if (checkChildren) { break; } } else if (entity.isDescendant(entities[i].getName())) { checkChildren = true; if (checked) { break; } } } if (checkChildren) { VObject[] children = object.getChildren(); for (int i = 0; i < children.length; i++) { apply(rule, children[i]); } } } private void notifyStarted() { running = true; sleeping = false; synchronized (listeners) { for (int i = 0; i < listeners.size(); i++) { SafeRunner.run(new OnStartNotifier((VTaskListener)listeners.get(i))); } } } private void logListener(VTaskListener listener, Throwable e) { VerificationPlugin.getPluginLog().logInfo("Exception in listener "+listener+" ignored: "+e, e); //$NON-NLS-1$ //$NON-NLS-2$ } private void notifyApplied(VRule rule, VObject object, VResult[] results) { synchronized (listeners) { for (int i = 0; i < listeners.size(); i++) { SafeRunner.run(new OnRuleAppliedNotifier((VTaskListener)listeners.get(i),rule, object, results)); } } } private void notifyRuleFinished(VRule rule, VObject object) { if(!running) return; synchronized (listeners) { for (int i = 0; i < listeners.size(); i++) { SafeRunner.run(new OnRuleFinishedNotifier((VTaskListener)listeners.get(i),rule, object)); } } } private void notifyPause() { if(!running) return; synchronized (listeners) { for (int i = 0; i < listeners.size(); i++) { SafeRunner.run(new OnPauseNotifier((VTaskListener)listeners.get(i))); } } } private void notifyResume() { if(!running) return; synchronized (listeners) { for (int i = 0; i < listeners.size(); i++) { SafeRunner.run(new OnResumeNotifier((VTaskListener)listeners.get(i))); } } } private void notifyFinish() { sleeping = false; running = false; thread = null; VTaskListener[] ls = null; synchronized (listeners) { ls = (VTaskListener[])listeners.toArray(new VTaskListener[0]); } for (int i = 0; i < ls.length; i++) { SafeRunner.run(new OnFinishNotifier(ls[i])); } } public void addTaskListener(VTaskListener listener) { synchronized (listeners) { listeners.add(listener); } } public void removeTaskListener(VTaskListener listener) { synchronized (listeners) { listeners.remove(listener); } } public class SafeNotifier implements ISafeRunnable { protected VTaskListener listener; public SafeNotifier(VTaskListener listener) { this.listener = listener; } public void run() throws Exception { listener.onStart(); } public void handleException(Throwable exception) { logListener(listener, exception); } } public class OnStartNotifier extends SafeNotifier { public OnStartNotifier(VTaskListener listener) { super(listener); } public void run() throws Exception { listener.onStart(); } } public class OnPauseNotifier extends SafeNotifier { public OnPauseNotifier(VTaskListener listener) { super(listener); } public void run() throws Exception { listener.onPause(); } } public class OnResumeNotifier extends SafeNotifier { public OnResumeNotifier(VTaskListener listener) { super(listener); } public void run() throws Exception { listener.onResume(); } } public class OnFinishNotifier extends SafeNotifier { public OnFinishNotifier(VTaskListener listener) { super(listener); } public void run() throws Exception { listener.onFinish(); } } public class OnRuleFinishedNotifier extends SafeNotifier { VRule rule; VObject object; public OnRuleFinishedNotifier(VTaskListener listener,VRule rule, VObject object) { super(listener); this.rule = rule; this.object = object; } public void run() throws Exception { listener.onRuleFinished(rule, object); } } public class OnRuleAppliedNotifier extends OnRuleFinishedNotifier { VResult[] results; public OnRuleAppliedNotifier(VTaskListener listener,VRule rule, VObject object, VResult[] results) { super(listener,rule,object); this.results =results; } public void run() throws Exception { listener.onRuleApplied(rule, object, results); } } }