com.symbian.driver.launch.DriverLaunch.java Source code

Java tutorial

Introduction

Here is the source code for com.symbian.driver.launch.DriverLaunch.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.launch;

import java.io.IOException;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.cli.ParseException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.ui.progress.IProgressConstants;

import com.symbian.driver.Build;
import com.symbian.driver.CmdPC;
import com.symbian.driver.CmdSymbian;
import com.symbian.driver.Reference;
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.ResourceLoader;
import com.symbian.driver.core.controller.PCVisitor;
import com.symbian.driver.core.controller.SymbianVisitor;
import com.symbian.driver.core.controller.Visitor;
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.environment.TDConfig;
import com.symbian.driver.presentation.DriverEditorPlugin;
import com.symbian.driver.report.views.ShowView;
import com.symbian.driver.report.views.TestViewer;
import com.symbian.driver.utils.EclipseLogger;
import com.symbian.driver.utils.TDGUIConfigLogging;
import com.symbian.driver.utils.TestDriverConfigurator;
import com.symbian.driver.utils.UIUtils;

/**
 * @author EngineeringTools
 * 
 * Launches Test Driver
 * 
 */
public class DriverLaunch implements ILaunchConfigurationDelegate {

    /** iRBuild : Boolean for Test Driver RBuild */
    private Boolean iRBuild;

    private static final ISchedulingRule iSingleJob = new SingleJob();

    /**
     * launch : launches Test Driver It uses Eclipse jobs to schedule the
     * TestDriver build/run
     * 
     * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration,
     *      java.lang.String, org.eclipse.debug.core.ILaunch,
     *      org.eclipse.core.runtime.IProgressMonitor)
     */
    public void launch(ILaunchConfiguration aConfiguration, String aMode, ILaunch aLaunch,
            IProgressMonitor aMonitor) throws CoreException {

        String lMode = aMode;
        //get a copy of the launch configuration. we do not need refrence to the original as 
        //from now on this config will not change.

        final ILaunchConfigurationWorkingCopy lEclipseConfig = aConfiguration.copy("aCopy");

        int lRunType = DriverLaunchConstants.BUILD_RUN;
        iRBuild = lEclipseConfig.getAttribute(DriverLaunchConstants.RBUILD, true);

        // this should never happen but just in case
        if (!lMode.equalsIgnoreCase("run")) {
            IStatus lStatus = EclipseLogger.createStatus(IStatus.ERROR, IStatus.ERROR,
                    "Mode : " + lMode + " is not supported.", null);
            ErrorDialog.openError(UIUtils.getShell(), "TestDriver Launcher", "TestDriver failed to launch...",
                    lStatus);
            return;
        }

        String lTask = DriverLaunchConstants.DRIVER;
        // get the run type buid/run/both default both.
        try {
            lRunType = lEclipseConfig.getAttribute(DriverLaunchConstants.RUN_TYPE, lRunType);
            lTask = lEclipseConfig.getAttribute(DriverLaunchConstants.ENTRY_POINT_ADDRESS, lTask);
        } catch (CoreException lException) {
            EclipseLogger.logInfo("Failed to get the run type, therefore using default BOTH Build+Run");
        }

        DeviceUtils.resetPoll();

        // create a job or jobs and schedule them.
        Job lJob;
        if (lRunType == DriverLaunchConstants.BUILD) {
            // create a build job and schedule it
            lJob = createJob(lEclipseConfig, true, true, false);
            lJob.setName("TestDriver : Build : " + lTask);
            lJob.setRule(iSingleJob);
            lJob.schedule();
        } else if (lRunType == DriverLaunchConstants.RUN) {
            // create a run job and schedule it
            lJob = createJob(lEclipseConfig, false, true, false);
            lJob.setName("TestDriver : Run : " + lTask);
            lJob.setRule(iSingleJob);
            lJob.schedule();
        } else if (lRunType == DriverLaunchConstants.BUILD_RUN) {
            // create a build job and schedule it
            lJob = createJob(lEclipseConfig, true, true, true);
            lJob.setName("TestDriver : Build : " + lTask);
            lJob.setRule(iSingleJob);
            lJob.schedule();

            // create a run job and schedule it
            lJob = createJob(lEclipseConfig, false, false, false);
            lJob.setName("TestDriver : Run : " + lTask);
            lJob.setRule(iSingleJob);
            lJob.schedule();
        }
    }

    /**
     * creatJob : create an eclipse Job
     * 
     * @param Task
     *            aTask : The root task to run
     * @param int
     *            aNumberOfTasks : the number of tasks to run
     * @param boolean
     *            aIsBuild : true = build, false = run
     * 
     * @param boolean
     *            aClearConsole : clear the console. This will be used for
     *            build+run to keep the console between jobs.
     * @return Job
     */
    public Job createJob(final ILaunchConfiguration aLaunchConfig, final boolean aIsBuild,
            final boolean aCleanConsole, final boolean aKeepLog) {

        final Job lJob = new Job("Test Driver Job") {

            private Logger LOGGER;

            private Task lTask = null;

            protected IStatus run(final IProgressMonitor aProgressMonitor) {

                class ProgressMonitorThread extends Thread {

                    private IProgressMonitor iProgressMonitor = aProgressMonitor;
                    private boolean isDone = false;

                    public void run() {
                        while (!isDone) {
                            if (iProgressMonitor.isCanceled()) {
                                DeviceUtils.stopPoll();
                                break;
                            }
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException ignore) {
                            }
                        }
                    }

                    public void done() {
                        isDone = true;
                    }
                }
                ;

                ProgressMonitorThread lProgressCancel = new ProgressMonitorThread();
                lProgressCancel.start();

                // configure logging again this will happen when the job starts
                TDGUIConfigLogging lLogConf = TDGUIConfigLogging.getInstance();
                lLogConf.configureLogging(aKeepLog);

                UIUtils.getDisplay().asyncExec(new ShowView());

                LOGGER = Logger.getLogger(Job.class.getName());

                LOGGER.info("\n\n*******Starting Job : " + this.getName());

                // configure TestDriver from Preferences and launch
                // configuration
                try {
                    TestDriverConfigurator.configTestDriver(aLaunchConfig);
                } catch (ParseException lParseException) {
                    return new Status(IStatus.ERROR, DriverEditorPlugin.ID, IStatus.ERROR,
                            this.getName() + " failed to set TestDriver configuration, see TestDriver log file.",
                            lParseException);
                }

                TDConfig CONFIG = TDConfig.newInstance();

                try {
                    CONFIG.printConfig(true);
                } catch (IOException lException) {
                    LOGGER.log(Level.SEVERE, lException.getMessage(), lException);
                }

                // try to load the driver file and get the task for real.
                try {
                    ResourceLoader.resetResourceSet();
                    lTask = ResourceLoader.load();
                } catch (ParseException lPex) {
                    // log and error and finish the Job
                    LOGGER.log(Level.SEVERE, "Failed to load resource : " + lPex.getMessage(), lPex);
                    return new Status(IStatus.ERROR, DriverEditorPlugin.ID, IStatus.ERROR,
                            this.getName() + " failed to load the driver file, please check your configuration.",
                            lPex);
                }

                if (lTask == null) {
                    return new Status(IStatus.ERROR, DriverEditorPlugin.ID, IStatus.ERROR,
                            this.getName()
                                    + " --- failed to find the requested suite, please check your configuration.",
                            null);
                }
                int lNumberOfTasks = 1;

                for (Iterator lTaskIter = lTask.eAllContents(); lTaskIter.hasNext();) {
                    Object lObject = lTaskIter.next();
                    // this list must much the visitor listerners we are passing
                    // in the job.
                    if (aIsBuild) {
                        if (lObject instanceof Task || lObject instanceof CmdPC || lObject instanceof Build
                                || lObject instanceof TestExecuteScript || lObject instanceof Transfer
                                || lObject instanceof Reference || lObject instanceof CmdSymbian
                                || lObject instanceof Rtest) {
                            lNumberOfTasks++;
                        }
                    } else {
                        if (lObject instanceof Task || lObject instanceof TestExecuteScript
                                || lObject instanceof Transfer || lObject instanceof Reference
                                || lObject instanceof CmdSymbian || lObject instanceof Rtest) {
                            lNumberOfTasks++;
                        }
                    }
                }
                // add parent levels
                lNumberOfTasks = lNumberOfTasks + lTask.getLevel();

                aProgressMonitor.beginTask((aIsBuild ? "Building" : "Running") + " task " + lTask.getName(),
                        lNumberOfTasks);

                final Visitor lVisitor;

                if (aIsBuild) {
                    lVisitor = new PCVisitor();
                    ((PCVisitor) lVisitor).setRBuild(iRBuild);
                } else {
                    lVisitor = new SymbianVisitor();
                }

                // show the Test Result view

                UIUtils.getDisplay().asyncExec(new Runnable() {
                    public void run() {
                        TestViewer.getInstance().setInput(lVisitor.getResult().getReport());
                    }
                });

                lVisitor.addVisitorListener(new IVisitorEventListener() {

                    public void taskFinished(TaskFinishedEvent aVisitorEvent) {

                        EObject lVisitObject = aVisitorEvent.getEObject();
                        if (lVisitObject instanceof Task) {
                            aProgressMonitor.subTask("Finished task: " + ((Task) lVisitObject).getName());
                        } else if (lVisitObject instanceof CmdPC) {
                            aProgressMonitor
                                    .subTask("Finished Running PC command: " + ((CmdPC) lVisitObject).getURI());
                        } else if (lVisitObject instanceof Build) {
                            aProgressMonitor
                                    .subTask("Finished Building group dir: " + ((Build) lVisitObject).getURI());
                        } else if (lVisitObject instanceof TestExecuteScript) {
                            if (aIsBuild) {
                                aProgressMonitor.subTask("Finished Copying TEF Script to repository: "
                                        + ((TestExecuteScript) lVisitObject).getPCPath());
                            } else {
                                aProgressMonitor.subTask("Finished Running TEF Script: "
                                        + ((TestExecuteScript) lVisitObject).getPCPath());
                            }
                        } else if (lVisitObject instanceof Transfer) {
                            if (aIsBuild) {
                                aProgressMonitor.subTask("Finished Copying Transfer file to repository: "
                                        + ((Transfer) lVisitObject).getPCPath());
                            } else {
                                aProgressMonitor.subTask("Finished Retrieve file to results: "
                                        + ((Transfer) lVisitObject).getPCPath());
                            }
                        } else if (lVisitObject instanceof Reference) {
                            aProgressMonitor.subTask(
                                    "Finished Reference: " + ((Reference) lVisitObject).getUri().getName());
                        } else if (lVisitObject instanceof CmdSymbian) {
                            aProgressMonitor.subTask("Finished Running Symbian command: "
                                    + ((CmdSymbian) lVisitObject).getStatCommand().getLiteral());
                        } else if (lVisitObject instanceof Rtest) {
                            aProgressMonitor
                                    .subTask("Finished Running RTest: " + ((Rtest) lVisitObject).getSymbianPath());
                        }

                        aProgressMonitor.worked(1);
                        // if the job has been canceled, ask the visistor to
                        // stop at the end of the task
                        if (aProgressMonitor.isCanceled()) {
                            lVisitor.stop();
                        }

                    }

                    public void taskStarted(TaskStartedEvent aVisitorEvent) {
                        EObject lVisitObject = aVisitorEvent.getEObject();
                        if (lVisitObject instanceof Task) {
                            aProgressMonitor.subTask("Started task: " + ((Task) lVisitObject).getName());
                        } else if (lVisitObject instanceof CmdPC) {
                            aProgressMonitor
                                    .subTask("Started Running PC command: " + ((CmdPC) lVisitObject).getURI());
                        } else if (lVisitObject instanceof Build) {
                            aProgressMonitor
                                    .subTask("Started Building group dir: " + ((Build) lVisitObject).getURI());
                        } else if (lVisitObject instanceof TestExecuteScript) {
                            if (aIsBuild) {
                                aProgressMonitor.subTask("Started Copying TEF Script to repository: "
                                        + ((TestExecuteScript) lVisitObject).getPCPath());
                            } else {
                                aProgressMonitor.subTask("Started Running TEF Script: "
                                        + ((TestExecuteScript) lVisitObject).getPCPath());
                            }
                        } else if (lVisitObject instanceof Transfer) {
                            if (aIsBuild) {
                                aProgressMonitor.subTask("Started Copying Transfer file to repository: "
                                        + ((Transfer) lVisitObject).getPCPath());
                            } else {
                                aProgressMonitor.subTask("Started Retrieve file to results: "
                                        + ((Transfer) lVisitObject).getPCPath());
                            }
                        } else if (lVisitObject instanceof Reference) {
                            aProgressMonitor
                                    .subTask("Started Reference: " + ((Reference) lVisitObject).getUri().getName());
                        } else if (lVisitObject instanceof CmdSymbian) {
                            aProgressMonitor.subTask("Started Running Symbian command: "
                                    + ((CmdSymbian) lVisitObject).getStatCommand().getLiteral());
                        } else if (lVisitObject instanceof Rtest) {
                            aProgressMonitor
                                    .subTask("Started Running RTest: " + ((Rtest) lVisitObject).getSymbianPath());
                        }
                    }
                });

                try {
                    // set our security manager to disallow TestDriver to kill the
                    // JVM with system.exit()

                    SecurityManager lSec = System.getSecurityManager();
                    LOGGER.fine("Installing Security Manager around Test Driver.");
                    System.setSecurityManager(new TestDriverRunnerSecurityManager());
                    lVisitor.start(lTask);

                    // remove security manager
                    LOGGER.fine("Removing Security Manager");
                    System.setSecurityManager(lSec);

                } catch (SecurityException lSecException) {
                    // ignore security exception. TestDriver has System.exit()
                }

                aProgressMonitor.done();
                lProgressCancel.done();

                return new Status(IStatus.OK, DriverEditorPlugin.ID, IStatus.OK,
                        "TestDriver " + (aIsBuild ? "Build" : "Run") + " Finished ", null);
            }
        };

        lJob.setUser(true);
        lJob.setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);

        return lJob;
    }
}

/**
 * 
 * @author Engineering Tools SingleJob is a an ISechedulingRule used to run
 *         TestDriver jobs in sequence. The rule is that if there a running job
 *         with the same rule then wait. All TestDriver jobs will be set with
 *         this rule Other eclipse jobs are not affected by this rule unless of
 *         course they want to use this rule.
 * 
 */
class SingleJob implements ISchedulingRule {

    public boolean contains(ISchedulingRule rule) {
        return rule == this;
    }

    public boolean isConflicting(ISchedulingRule rule) {
        return rule == this;
    }
}