com.symbian.driver.core.controller.Visitor.java Source code

Java tutorial

Introduction

Here is the source code for com.symbian.driver.core.controller.Visitor.java

Source

/*
* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/

package com.symbian.driver.core.controller;

import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.event.EventListenerList;

import org.apache.commons.cli.ParseException;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;

import com.symbian.driver.Build;
import com.symbian.driver.CmdPC;
import com.symbian.driver.CmdSymbian;
import com.symbian.driver.Rtest;
import com.symbian.driver.Task;
import com.symbian.driver.TestExecuteScript;
import com.symbian.driver.Transfer;
import com.symbian.driver.core.controller.event.IVisitorEventListener;
import com.symbian.driver.core.controller.event.TaskFinishedEvent;
import com.symbian.driver.core.controller.event.TaskStartedEvent;
import com.symbian.driver.core.controller.utils.DeviceUtils;
import com.symbian.driver.core.controller.utils.ModelUtils;
import com.symbian.driver.core.environment.TDConfig;
import com.symbian.driver.core.extension.IVisitor;
import com.symbian.driver.core.extension.IVisitor.ESeverity;
import com.symbian.driver.core.pluginProxies.RebootProxy;
import com.symbian.driver.core.processors.PreProcessor;
import com.symbian.driver.core.report.Result;
import com.symbian.driver.util.DriverSwitch;
import com.symbian.utils.Epoc;

/**
 * This is the main TestDriver class that walks through the EMF tree.
 * 
 * It uses the Visitor pattern implemented by using EMF's Switch Interface.
 * 
 * @author EnginneringTools
 */
public abstract class Visitor {

    // Constants
    /** The logger for the Visitor class. */
    protected static final Logger LOGGER = Logger.getLogger(Visitor.class.getName());

    protected final TDConfig CONFIG = TDConfig.getInstance();

    // Protected Variables
    /** The stack of tasks, pertaining to one node. */
    protected static Task sTask = null;

    // Private Variables
    /** The List of all event listeners. */
    private EventListenerList iEventListenerList = new EventListenerList();

    /** A Stop variable */
    private boolean iStop = false;

    /** The result object */
    private Result iResult;

    /** Switch to run all EMF Objects over. */
    private DriverSwitch iDriverSwitch;

    /** The PreProcessor to control the device. */
    private PreProcessor iSymbianDevice;

    private boolean iIsPCVisitor = false;

    private boolean iResultListener = false;

    /** Stack of previous Tasks. */
    protected static final Stack<Task> TASK_SET = new Stack<Task>();

    protected int iPreviousLevel = 0;

    private boolean iNoErrors = true;

    // ///////////////////////////////////////////////
    // Starts and Stops the visitors.
    // ///////////////////////////////////////////////

    public Visitor() {
        iResult = new Result();
    }

    /**
     * @param aTask
     * @return 
     */
    public abstract boolean start(final Task aTask);

    /**
     * Walks through the EMF tree, processing only the tasks specified by the
     * "Entry Point Address" and below.
     * 
     * This method relays the actual processing of each task to the necessary
     * Visitors. Note that this method must be called from the sub-classes in
     * their respective constructors.
     * 
     * @param aVisitor
     *            A link to the calling visitor.
     * @param aTask
     *            The root level task in the EMF tree.
     * @return 
     */
    protected boolean start(final Task aTask, final DriverSwitch aDriverSwitch, final PreProcessor aSymbianDevice,
            final boolean lResultListener) {
        iNoErrors = true;
        iIsPCVisitor = this instanceof PCVisitor;
        iResultListener = lResultListener;

        iDriverSwitch = aDriverSwitch;
        iSymbianDevice = aSymbianDevice;

        // Add Listener for reporting.
        if (iResultListener) {
            if (!iResult.initResult(this, aTask, iIsPCVisitor)) {
                LOGGER.log(Level.SEVERE, " Failed to initialize results.");
                iNoErrors = false;
            }
        }

        // request ModelUtils to clear the eclipsing stack
        ModelUtils.resetStack();

        // Execute all the tasks
        walkParents(aTask.eContainer());
        doEObject(aTask);
        walkChildren(aTask);

        // Transform Results at the end
        if (iResultListener) {
            iResult.doXSLT(iIsPCVisitor);
        }
        return iNoErrors;
    }

    /**
     * Stops the Visitor of TestDriver at the next Task.
     * 
     * @return 
     */
    public boolean stop() {
        iStop = true;
        return true;
    }

    // ///////////////////////////////////////////////
    // Methods that walk through the EMF tree.
    // ///////////////////////////////////////////////

    /**
     * Walks through the parents of a node in an EMF tree.
     * 
     * @param aTask
     *            The task to walk all the parents.
     * @param aVisitor
     *            The vistor that does the switch on each of the parent nodes.
     * @return The task currently being walked.
     */
    private final void walkParents(final EObject aTask) {
        if (iStop) {
            return;
        }

        if (aTask instanceof Task) {
            walkParents(aTask.eContainer());
            doEObject(aTask);
            EList lList = aTask.eContents();
            for (Iterator lItertoplevel = lList.iterator(); lItertoplevel.hasNext();) {
                EObject element = (EObject) lItertoplevel.next();
                if (!(element instanceof Task)) {
                    walkChildren(element);
                }
            }
        }
    }

    /**
     * Walks one tree specified by the iterator and executes the switch.
     * 
     * @param aDriverSwitch
     *            The switch to execute.
     * @param aIterator
     *            The tree to walk.
     */
    private final void walkChildren(final EObject aTask) {
        for (Iterator lIter = aTask.eAllContents(); lIter.hasNext();) {
            if (iStop) {
                return;
            }
            doEObject((EObject) lIter.next());
        }
    }

    private void doEObject(final EObject aEObject) {
        fireTaskStartedEvent(new TaskStartedEvent(aEObject, this instanceof PCVisitor));
        if (aEObject instanceof Task) {
            LOGGER.info("Visiting Task: " + ((Task) aEObject).getAddress());
            sTask = (Task) aEObject;
            try {
                // reboot device is relevant to hardware only.
                boolean lEmulator = Epoc.isTargetEmulator(TDConfig.getInstance().getPreference(TDConfig.PLATFORM));
                if (!lEmulator && this instanceof SymbianVisitor && ((Task) aEObject).isPreRebootDevice() == true) {
                    // first try soft reboot reboot
                    boolean lSoftRebooted = false;
                    if (DeviceUtils.restartBoard()) {
                        //wait for device communication service to run up
                        try {
                            Thread.sleep(10000); //10 seconds
                        } catch (InterruptedException e) {
                            //do nothing
                        }

                        if (DeviceUtils.poll(null)) {
                            lSoftRebooted = true;
                            LOGGER.log(Level.INFO, "JStat Reboot done on Device");
                        }
                    }

                    //soft reboot failed, try RebootProxy
                    if (!lSoftRebooted) {
                        try {
                            if (RebootProxy.getInstance().Reboot()) {
                                LOGGER.log(Level.INFO, "Reboot done on Device via reboot plugin.");
                            } else {
                                LOGGER.log(Level.SEVERE, "Could not reboot Device using reboot plugin");
                                iNoErrors = false;
                            }
                        } catch (Exception lException) {
                            LOGGER.log(Level.SEVERE, "Could not reboot thru any plugins either", lException);
                            iNoErrors = false;
                        }
                    }
                }
            } catch (ParseException lParseException) {
                LOGGER.log(Level.SEVERE, "Configuration error", lParseException);
                iNoErrors = false;
            }
        } else {
            EObject parent = aEObject.eContainer();
            if (parent instanceof Task) {
                sTask = (Task) parent;
            }
        }

        // Start EMF Node

        IVisitor lVisitor = (IVisitor) iDriverSwitch.doSwitch(aEObject);
        Map<? extends Exception, ESeverity> lResult = null;
        if (lVisitor != null) {
            lResult = lVisitor.execute(sTask, iSymbianDevice);
        }
        if (lResult != null && !lResult.isEmpty() && lResult.containsValue(ESeverity.ERROR)) {
            iNoErrors = false;
        }

        if (iResultListener) {
            if (iIsPCVisitor) {
                if (aEObject instanceof Build || aEObject instanceof TestExecuteScript
                        || aEObject instanceof Transfer || aEObject instanceof CmdPC) {
                    fireTaskFinishedEvent(
                            new TaskFinishedEvent(aEObject, this instanceof PCVisitor, false, lResult));
                }
            } else if (aEObject instanceof CmdSymbian || aEObject instanceof Rtest
                    || aEObject instanceof TestExecuteScript || aEObject instanceof Transfer) {
                fireTaskFinishedEvent(new TaskFinishedEvent(aEObject, this instanceof PCVisitor, false, lResult));
            }
        }
    }

    // ///////////////////////////////////////////////
    // Listener's for all the Visitors.
    // ///////////////////////////////////////////////

    /**
     * Add a listner to the events of the Visitor.
     * 
     * The listner must implement VisitorEventListner. This listner has methods
     * for when a tasks starts, stops sucesfully and fails. Uses standard Java
     * Listner pattern.
     * 
     * @param aEventListener
     *            The event listener to add.
     */
    public final void addVisitorListener(IVisitorEventListener aEventListener) {
        iEventListenerList.add(IVisitorEventListener.class, aEventListener);
    }

    /**
     * Removes a listner that has been added to the Vistitor class.
     * 
     * @param aEventListener
     *            The event listener to remove.
     */
    public final void removeVisitorListener(IVisitorEventListener aEventListener) {
        iEventListenerList.remove(IVisitorEventListener.class, aEventListener);
    }

    /**
     * Fires the "Execute Started Event" to all relevant listners.
     * 
     * @param aVisitorEvent
     *            The event to fire to the listener.
     */
    private final void fireTaskStartedEvent(TaskStartedEvent aVisitorEvent) {
        Object[] lListeners = iEventListenerList.getListenerList();

        // loop through each listener and pass on the event if needed
        for (int lIter = lListeners.length - 2; lIter >= 0; lIter -= 2) {
            if (lListeners[lIter] == IVisitorEventListener.class) {
                ((IVisitorEventListener) lListeners[lIter + 1]).taskStarted(aVisitorEvent);
            }
        }
    }

    /**
     * Fires the "Execute Finished Event" to all relevant listners.
     * 
     * @param aVisitorEvent
     *            The event to fire to the listener.
     */
    protected final void fireTaskFinishedEvent(TaskFinishedEvent aVisitorEvent) {
        Object[] lListeners = iEventListenerList.getListenerList();

        // loop through each listener and pass on the event if needed
        for (int lIter = lListeners.length - 2; lIter >= 0; lIter -= 2) {
            if (lListeners[lIter] == IVisitorEventListener.class) {
                ((IVisitorEventListener) lListeners[lIter + 1]).taskFinished(aVisitorEvent);
            }
        }
    }

    // ///////////////////////////////////////////////
    // Utility methods.
    // ///////////////////////////////////////////////

    /**
     * @return
     */
    public Result getResult() {
        return iResult;
    }
}