Package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.actions.manual

Source Code of com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.actions.manual.TriggerMonitor$EventState

/*
* The MIT License
*
* Copyright 2010 Sony Ericsson Mobile Communications. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.actions.manual;

import com.sonymobile.tools.gerrit.gerritevents.dto.GerritEvent;
import com.sonyericsson.hudson.plugins.gerrit.trigger.events.lifecycle.GerritEventLifecycle;
import com.sonyericsson.hudson.plugins.gerrit.trigger.events.lifecycle.GerritEventLifecycleListener;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.TriggeredItemEntity;

import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BallColor;
import hudson.model.Result;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
* Keeps track of the lifecycle of a GerritEvent.
* @author Robert Sandell <robert.sandell@sonyericsson.com>
*/
public class TriggerMonitor implements GerritEventLifecycleListener {

    private List<EventState> events = new LinkedList<EventState>();

    /**
     * Adds the event and a holder for its state to the list of triggered events.
     * And adds this TriggerMonitor as a listener to the event.
     * Unless it doesn't already exists in the list of events.
     * @param gerritEventLifecycle the event.
     */
    public synchronized void add(GerritEventLifecycle gerritEventLifecycle) {
        if (!contains(gerritEventLifecycle)) {
            gerritEventLifecycle.addListener(this);
            events.add(new EventState(gerritEventLifecycle));
        }
    }

    /**
     * Checks to see if the list of triggered events and their states contains the given event.
     * @param gerritEventLifecycle the event to check.
     * @return true if it exests in the list.
     * @see #getEvents()
     */
    public synchronized boolean contains(GerritEventLifecycle gerritEventLifecycle) {
        if (findState(gerritEventLifecycle.getEvent()) != null) {
           return true;
        }
        return false;
    }

    /**
     * Finds the EventState containing the given event.
     * @param gerritEvent the event.
     * @return the state, or null if there is none.
     */
    private synchronized EventState findState(GerritEvent gerritEvent) {
        for (EventState state : events) {
            if (state.gerritEventLifecycle.getEvent().equals(gerritEvent)) {
                return state;
            }
        }
        return null;
    }

    @Override
    public synchronized void triggerScanStarting(GerritEvent event) {
        EventState state = findState(event);
        if (state != null) {
            state.triggerScanStarted = true;
        }
    }

    @Override
    public synchronized void triggerScanDone(GerritEvent event) {
        EventState state = findState(event);
        if (state != null) {
            state.triggerScanDone = true;
        }
    }

    @Override
    public synchronized void projectTriggered(GerritEvent event, AbstractProject project) {
        EventState state = findState(event);
        if (state != null) {
            state.addProject(project);
        }
    }

    @Override
    public synchronized void buildStarted(GerritEvent event, AbstractBuild build) {
        EventState state = findState(event);
        if (state != null) {
            state.setBuild(build);
        }
    }

    @Override
    public synchronized void buildCompleted(GerritEvent event, AbstractBuild build) {
        EventState state = findState(event);
        if (state != null) {
            if (state.allBuildsCompleted && state.isReallyAllBuildsCompleted()) {
                state.gerritEventLifecycle.removeListener(this);
            }
        }
    }

    @Override
    public synchronized void allBuildsCompleted(GerritEvent event) {
        EventState state = findState(event);
        if (state != null) {
            state.allBuildsCompleted = true;
            if (state.isReallyAllBuildsCompleted()) {
                state.gerritEventLifecycle.removeListener(this);
            }
        }
    }

    /**
     * The list of events and their states.
     * @return a list.
     */
    public synchronized List<EventState> getEvents() {
        return events;
    }

    /**
     * An iterator of the list of events and their states.
     * @return a iterator.
     */
    @SuppressWarnings("unused") //called from Jelly
    public synchronized Iterator<EventState> getEventsIterator() {
        return events.iterator();
    }

    /**
     * State information about an event.
     */
    public static class EventState {
        private GerritEventLifecycle gerritEventLifecycle;
        private boolean triggerScanStarted = false;
        private boolean triggerScanDone = false;
        private boolean allBuildsCompleted = false;
        private List<TriggeredItemEntity> builds;

        /**
         * Standard constructor.
         * @param gerritEventLifecycle the event to track.
         */
        EventState(GerritEventLifecycle gerritEventLifecycle) {
            this.gerritEventLifecycle = gerritEventLifecycle;
            builds = new LinkedList<TriggeredItemEntity>();
        }

        /**
         * Adds a project to the list of triggered projects.
         * @param project the project.
         */
        void addProject(AbstractProject project) {
            builds.add(new TriggeredItemEntity(project));
        }

        /**
         * Sets the started build to an already triggered project.
         * @param build the build.
         */
        void setBuild(AbstractBuild build) {
            for (TriggeredItemEntity entity : builds) {
                if (entity.equals(build.getProject())) {
                    entity.setBuild(build);
                }
            }
        }

        /**
         * Returns the appropriate ball color for the current status of this event and its builds.
         * @return the path to the image of the ball.
         * @see hudson.model.Result#color
         * @see hudson.model.BallColor#getImage()
         */
        @SuppressWarnings("unused") //called from jelly
        public String getBallColor() {
            if (!triggerScanStarted) {
                return BallColor.GREY.getImage();
            } else if (!triggerScanDone) {
                return BallColor.GREY_ANIME.getImage();
            } else if (isUnTriggered()) {
                return BallColor.DISABLED.getImage();
            } else {
                Result result = getLeastFavorableResult();
                if (result != null) {
                    return result.color.getImage();
                } else {
                    return BallColor.GREY_ANIME.getImage();
                }
            }
        }

        /**
         * Gives the least favorable {@link hudson.model.Run#getResult()} in the list of build, if there is any results.
         * @return the result or null if there is none.
         */
        private Result getLeastFavorableResult() {
            Result least = null;
            for (TriggeredItemEntity entity : builds) {
                if (entity.getBuild() != null && entity.getBuild().getResult() != null) {
                    Result tmp = entity.getBuild().getResult();
                    if (least == null) {
                        least = tmp;
                    } else {
                        least = least.combine(tmp);
                    }
                }
            }
            return least;
        }

        /**
         * If no active triggers where interested in this event.
         * Determined by: {@link #isTriggerScanDone()} && {@link #getBuilds()}.size() <= 0
         * unless not {@link #isTriggerScanStarted()}.
         * @return true if so.
         */
        public boolean isUnTriggered() {
            if (!triggerScanStarted) {
                return false;
            } else {
                return triggerScanDone && builds.size() <= 0;
            }
        }

        /**
         * The event.
         * @return the event.
         */
        public GerritEventLifecycle getEvent() {
            return gerritEventLifecycle;
        }

        /**
         * If the active triggers in the system has started to be notified.
         * @return true if so.
         */
        public boolean isTriggerScanStarted() {
            return triggerScanStarted;
        }

        /**
         * If all the active triggers in the system has been notified about this event.
         * @return true if so.
         */
        public boolean isTriggerScanDone() {
            return triggerScanDone;
        }

        /**
         * If all builds started by this event has completed.
         * @return true if so.
         */
        public boolean isAllBuildsCompleted() {
            return allBuildsCompleted;
        }

        /**
         * Gets the builds that has started for this event.
         * @return the builds.
         */
        public List<TriggeredItemEntity> getBuilds() {
            return builds;
        }

        /**
         * Goes through the list of builds and checks if anyone is still building.
         * Even though the event {@link TriggerMonitor#allBuildsCompleted(GerritEvent)}
         * has been called that only applies to non silent builds, an extra check is needed.
         * @return true if all builds has completed.
         */
        public boolean isReallyAllBuildsCompleted() {
            for (TriggeredItemEntity entity : builds) {
                if (entity.getBuild() == null || !entity.getBuild().isLogUpdated()) {
                    return false;
                }
            }
            return true;
        }
    }
}
TOP

Related Classes of com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.actions.manual.TriggerMonitor$EventState

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.