diff options
Diffstat (limited to 'dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/ReflectionSequence.java')
-rw-r--r-- | dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/ReflectionSequence.java | 331 |
1 files changed, 168 insertions, 163 deletions
diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/ReflectionSequence.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/ReflectionSequence.java index e4c6f2810e9..ace6092de20 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/ReflectionSequence.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/ReflectionSequence.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -34,23 +34,23 @@ import org.eclipse.core.runtime.Status; * A type of {@link Sequence} which uses reflection and annotations to * declare its different {@link Sequence.Step}. It can be used to make * larger DSF sequences more readable and easier to override. - * + * * The order of execution of the {@code @Execute} methods is determined by - * the {@link #getExecutionOrder()} method. - * + * the {@link #getExecutionOrder()} method. + * * {@code @Execute} methods can be grouped in a hierarchical set of groups, * which should be included in the result of {@link #getExecutionOrder()}. * Using groups can make overriding slightly simpler. - * + * * A usage example follows: <code><pre> * public class MyReflectionSequence extends ReflectionSequence { * * public MyReflectionSequence(DsfExecutor executor) { * super(executor); * } - * + * * protected static final String GROUP_INIT = "GROUP_INIT"; - * + * * {@code @Override} * protected String[] getExecutionOrder(String group) { * if (GROUP_TOP_LEVEL.equals(group)) { @@ -59,12 +59,12 @@ import org.eclipse.core.runtime.Status; * // other groups. * return new String[] { GROUP_INIT, "step3", "step4" }; * } - * + * * // Now deal with the content of sub-groups * if (GROUP_INIT.equals(group)) { * return new String[] { "step1", "step2" }; * } - * + * * // An invalid group was requested * return null; * } @@ -72,35 +72,35 @@ import org.eclipse.core.runtime.Status; * {@code @Execute} * public void step1(RequestMonitor rm) { * // Do something - * rm.done(); + * rm.done(); * } * * {@code @RollBack("step1")} * public void rollBack1(RequestMonitor rm) { * // Rollback what was done in step1() - * rm.done(); + * rm.done(); * } * * {@code @Execute} * public void step2(RequestMonitor rm) { * // Do something else - * rm.done(); + * rm.done(); * } - * + * * {@code @Execute} * public void step3(RequestMonitor rm) { * // Do something else - * rm.done(); + * rm.done(); * } * * {@code @Execute} * public void step4(RequestMonitor rm) { * // Do something else - * rm.done(); + * rm.done(); * } * } * </pre></code> - * + * * @since 2.2 */ abstract public class ReflectionSequence extends Sequence { @@ -111,157 +111,162 @@ abstract public class ReflectionSequence extends Sequence { * identifier is the one that will be used in the first call to * {@link #getExecutionOrder()}. */ - public static final String GROUP_TOP_LEVEL = "GROUP_TOP_LEVEL"; //$NON-NLS-1$ - + public static final String GROUP_TOP_LEVEL = "GROUP_TOP_LEVEL"; //$NON-NLS-1$ + private Step[] fReflectionSteps; - - /** - * Annotation used to indicate that a method corresponds to an - * {@link Sequence.Step#execute()} method of a {@link Sequence.Step}. - * The annotated method must be declared public. - */ - @Inherited - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public static @interface Execute {} - - /** - * Annotation used to indicate that a method corresponds to a - * {@link Sequence.Step#rollBack()} method of a {@link Sequence.Step}. - * Declaring such a method is optional. If declared, the annotated - * method must be declared public. - */ - @Inherited - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public static @interface RollBack { - /** - * Name of the method tagged with the {@link Execute} annotation that this method rolls back. - */ - String value(); - } - private class ReflectionStep extends Step { - final private Method fExecuteMethod; - final private Method fRollbackMethod; - - private ReflectionStep(Method executeMethod, Method rollbackMethod) { - assert executeMethod != null; - - fExecuteMethod = executeMethod;; - fRollbackMethod = rollbackMethod; - } - - @Override - public void execute(RequestMonitor rm) { - try { - fExecuteMethod.invoke(ReflectionSequence.this, rm); - } catch (Exception e) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error executing step execute method: " + fExecuteMethod.getName(), e)); //$NON-NLS-1$ - rm.done(); - } - } - - @Override - public void rollBack(RequestMonitor rm) { - if (fRollbackMethod == null) { - super.rollBack(rm); - } else { - try { - fRollbackMethod.invoke(ReflectionSequence.this, rm); - } catch (Exception e) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Error executing step rollback method: " + fRollbackMethod.getName(), e)); //$NON-NLS-1$ - rm.done(); - } - } - } - } + /** + * Annotation used to indicate that a method corresponds to an + * {@link Sequence.Step#execute()} method of a {@link Sequence.Step}. + * The annotated method must be declared public. + */ + @Inherited + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public static @interface Execute { + } + + /** + * Annotation used to indicate that a method corresponds to a + * {@link Sequence.Step#rollBack()} method of a {@link Sequence.Step}. + * Declaring such a method is optional. If declared, the annotated + * method must be declared public. + */ + @Inherited + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public static @interface RollBack { + /** + * Name of the method tagged with the {@link Execute} annotation that this method rolls back. + */ + String value(); + } + + private class ReflectionStep extends Step { + final private Method fExecuteMethod; + final private Method fRollbackMethod; + + private ReflectionStep(Method executeMethod, Method rollbackMethod) { + assert executeMethod != null; + + fExecuteMethod = executeMethod; + ; + fRollbackMethod = rollbackMethod; + } + + @Override + public void execute(RequestMonitor rm) { + try { + fExecuteMethod.invoke(ReflectionSequence.this, rm); + } catch (Exception e) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Error executing step execute method: " + fExecuteMethod.getName(), e)); //$NON-NLS-1$ + rm.done(); + } + } + + @Override + public void rollBack(RequestMonitor rm) { + if (fRollbackMethod == null) { + super.rollBack(rm); + } else { + try { + fRollbackMethod.invoke(ReflectionSequence.this, rm); + } catch (Exception e) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Error executing step rollback method: " + fRollbackMethod.getName(), e)); //$NON-NLS-1$ + rm.done(); + } + } + } + } + + public ReflectionSequence(DsfExecutor executor) { + super(executor); + } + + public ReflectionSequence(DsfExecutor executor, RequestMonitor rm) { + super(executor, rm); + } + + public ReflectionSequence(DsfExecutor executor, IProgressMonitor pm, String taskName, String rollbackTaskName) { + super(executor, pm, taskName, rollbackTaskName); + } + + public ReflectionSequence(DsfExecutor executor, RequestMonitorWithProgress rm, String taskName, + String rollbackTaskName) { + super(executor, rm, taskName, rollbackTaskName); + } + + /** + * This method must return the execution order of {@code @Execute} methods and/or groups. + * + * @param groupName The name of a group for which the list of {@code @Execute} methods + * or sub-groups should be returned in the order they should be executed. + * If the concept of groups is not used, then this parameter can be ignored, + * at the top-level ordering should be returned. + * + * @return An array containing the list of @Execute methods and groups in the order + * they should be executed, or null if the specified groupName is unknown. + */ + abstract protected String[] getExecutionOrder(String groupName); + + @Override + public Step[] getSteps() { + if (fReflectionSteps == null) { + Map<String, Method> executeMethods = getAnnotatedMethods(Execute.class); + Map<String, Method> rollBackMethods = getAnnotatedMethods(RollBack.class); + List<Step> steps = getGroupSteps(GROUP_TOP_LEVEL, executeMethods, rollBackMethods); + fReflectionSteps = steps.toArray(new ReflectionStep[steps.size()]); + } + return fReflectionSteps; + } + + private List<Step> getGroupSteps(String groupId, Map<String, Method> executeMethods, + Map<String, Method> rollBackMethods) { + List<Step> steps = new ArrayList<Step>(executeMethods.size()); - public ReflectionSequence(DsfExecutor executor) { - super(executor); - } - - public ReflectionSequence(DsfExecutor executor, RequestMonitor rm) { - super(executor, rm); - } + String[] order = getExecutionOrder(groupId); + if (order == null) { + throw new RuntimeException("Unknown group in sequence: " + groupId); //$NON-NLS-1$ + } - public ReflectionSequence(DsfExecutor executor, IProgressMonitor pm, String taskName, String rollbackTaskName) { - super(executor, pm, taskName, rollbackTaskName); - } - - public ReflectionSequence(DsfExecutor executor, RequestMonitorWithProgress rm, String taskName, String rollbackTaskName) { - super(executor, rm, taskName, rollbackTaskName); - } - - /** - * This method must return the execution order of {@code @Execute} methods and/or groups. - * - * @param groupName The name of a group for which the list of {@code @Execute} methods - * or sub-groups should be returned in the order they should be executed. - * If the concept of groups is not used, then this parameter can be ignored, - * at the top-level ordering should be returned. - * - * @return An array containing the list of @Execute methods and groups in the order - * they should be executed, or null if the specified groupName is unknown. - */ - abstract protected String[] getExecutionOrder(String groupName); - - @Override - public Step[] getSteps() { - if (fReflectionSteps == null) { - Map<String, Method> executeMethods = getAnnotatedMethods(Execute.class); - Map<String, Method> rollBackMethods = getAnnotatedMethods(RollBack.class); - List<Step> steps = getGroupSteps(GROUP_TOP_LEVEL, executeMethods, rollBackMethods); - fReflectionSteps = steps.toArray(new ReflectionStep[steps.size()]); - } - return fReflectionSteps; - } + for (String name : order) { + Method executeMethod = executeMethods.get(name); + if (executeMethod == null) { + // name is a group id + steps.addAll(getGroupSteps(name, executeMethods, rollBackMethods)); + } else { + steps.add(new ReflectionStep(executeMethod, rollBackMethods.get(executeMethod.getName()))); + } + } + return steps; + } - private List<Step> getGroupSteps(String groupId, Map<String, Method> executeMethods, Map<String, Method> rollBackMethods) { - List<Step> steps = new ArrayList<Step>(executeMethods.size()); - - String[] order = getExecutionOrder(groupId); - if (order == null) { - throw new RuntimeException("Unknown group in sequence: " + groupId); //$NON-NLS-1$ - } - - for (String name : order) { - Method executeMethod = executeMethods.get(name); - if (executeMethod == null) { - // name is a group id - steps.addAll(getGroupSteps(name, executeMethods, rollBackMethods)); - } else { - steps.add(new ReflectionStep(executeMethod, rollBackMethods.get(executeMethod.getName()))); - } - } - return steps; - } - - private Map<String, Method> getAnnotatedMethods(Class<? extends Annotation> annotationType) { - Map<String, Method> retVal = new HashMap<String, Method>(); - try { - Method[] methods = getClass().getMethods(); - for (Method method : methods) { - if (method.isAnnotationPresent(annotationType)) { - Class<?>[] paramTypes = method.getParameterTypes(); - if (paramTypes.length != 1) { // must have one and only param, the RequestMonitor - throw new IllegalArgumentException("Method " + //$NON-NLS-1$ - method.getDeclaringClass().getSimpleName() + "#" + method.getName() + //$NON-NLS-1$ - " must have a single parameter"); //$NON-NLS-1$ - } else { - if (annotationType.equals(Execute.class)) { - retVal.put(method.getName(), method); - } else {// @Rollback - retVal.put(method.getAnnotation(RollBack.class).value(), method); - } - } - } - } - } catch(SecurityException e) { - throw new IllegalArgumentException("No permission to access ReflectionSequence method"); //$NON-NLS-1$ - } - return retVal; - } - + private Map<String, Method> getAnnotatedMethods(Class<? extends Annotation> annotationType) { + Map<String, Method> retVal = new HashMap<String, Method>(); + try { + Method[] methods = getClass().getMethods(); + for (Method method : methods) { + if (method.isAnnotationPresent(annotationType)) { + Class<?>[] paramTypes = method.getParameterTypes(); + if (paramTypes.length != 1) { // must have one and only param, the RequestMonitor + throw new IllegalArgumentException("Method " + //$NON-NLS-1$ + method.getDeclaringClass().getSimpleName() + "#" + method.getName() + //$NON-NLS-1$ + " must have a single parameter"); //$NON-NLS-1$ + } else { + if (annotationType.equals(Execute.class)) { + retVal.put(method.getName(), method); + } else {// @Rollback + retVal.put(method.getAnnotation(RollBack.class).value(), method); + } + } + } + } + } catch (SecurityException e) { + throw new IllegalArgumentException("No permission to access ReflectionSequence method"); //$NON-NLS-1$ + } + return retVal; + } } |