package com.sonatype.buildserver.monitor;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.widgets.Display;
import org.hudsonci.rest.model.build.BuildDTO;
import org.hudsonci.rest.model.build.BuildStateDTO;
import org.hudsonci.rest.model.build.ChangesDTO;
import org.hudsonci.rest.model.build.ConsoleDTO;
import org.hudsonci.rest.model.build.TestsDTO;
import org.hudsonci.rest.model.project.ProjectDTO;
import org.hudsonci.rest.model.project.ProjectReferenceDTO;
{
final HudsonMonitor monitor;
final String jobId;
private List<BuildDTO> builds;
private ProjectDTO details;
private State detailsState = State.STATE_NOT_LOADED;
private State buildState = State.STATE_NOT_LOADED;
enum State
{
STATE_OK, STATE_LOADING, STATE_NOT_LOADED, STATE_DIRTY, STATE_FAILED
}
private Map<Integer, ChangesDTO> changes = new HashMap<Integer, ChangesDTO>();
private List<HudsonJobListener> listeners = new ArrayList<HudsonJobListener>();
private HudsonJobListener monitorListener = new HudsonJobListener()
{
public void getModified( AbstractHudsonJobEvent event )
{
if ( event.getModifiedJob() == HudsonJob.this )
{
refireEvent( event );
}
}
public boolean isUIUp()
{
boolean hasOne = false;
synchronized (listeners) {
for (HudsonJobListener list : listeners) {
if (list.isUIUp()) {
hasOne = true;
break;
}
}
}
return hasOne;
}
};
HudsonJob( String job, HudsonMonitor hudsonMonitor )
{
monitor = hudsonMonitor;
jobId = job;
}
HudsonJob( ProjectDTO details, HudsonMonitor hudsonMonitor )
{
assert Display.getCurrent() == null;
monitor = hudsonMonitor;
jobId = details.getName();
this.details = details;
detailsState = State.STATE_OK;
}
{
return monitor.getServerURI().toString();
}
{
if (jobId == null) {
if (details != null) {
return details.getName();
}
assert false : "no jobid, no details, we are doomed.";
}
return jobId;
}
{
return details;
}
return detailsState == State.STATE_OK;
}
{
this.details = details;
detailsState = result;
if ( buildState == State.STATE_OK )
{
buildState = State.STATE_DIRTY;
}
}
return monitor.isMonitoredJob( this );
}
return monitor.isProvidedJob( this );
}
{
assert Display.getCurrent() == null;
return monitor.build( this );
}
public void enable(
boolean enable )
throws Exception
{
assert Display.getCurrent() == null;
monitor.enable( this, enable );
}
{
monitor.removeJob( this );
}
{
refresh (true, false);
}
private void refresh(
boolean async,
boolean force) {
assert async || Display.getCurrent() == null;
if ( !force && detailsState == State.STATE_LOADING )
{
return;
}
detailsState = State.STATE_LOADING;
RetrieveJob jb = new RetrieveJob( monitor, this );
jb.schedule();
if (!async) {
try
{
jb.join();
}
catch ( InterruptedException e )
{
}
}
}
detailsState = State.STATE_LOADING;
}
{
if ( buildState == State.STATE_LOADING )
{
return;
}
buildState = State.STATE_LOADING;
monitor.scheduleBuildsRetrieval( this );
}
public void keepBuild( BuildDTO build,
boolean keep )
throws Exception
{
assert Display.getCurrent() == null;
monitor.keepBuild( this, build, keep );
}
public void deleteBuild( BuildDTO build )
throws Exception
{
assert Display.getCurrent() == null;
monitor.deleteBuild( this, build );
}
{
monitor.scheduleChangesRetrieval( this, build );
}
assert Display.getCurrent() == null;
List<HudsonJob> toRet = new ArrayList<HudsonJob>();
if (detailsState == State.STATE_NOT_LOADED || detailsState == State.STATE_DIRTY) {
refresh( false, true );
}
ProjectDTO details = getJobDetails();
if (details != null) {
List<ProjectReferenceDTO> refs = details.getDescendants();
for (ProjectReferenceDTO ref : refs) {
HudsonJob bj = monitor.hudsonJobForReference( ref );
if (bj != null) {
toRet.add( bj );
}
}
}
return toRet;
}
@Override
{
final int prime = 31;
int result = 1;
result = prime * result + jobId.hashCode();
result = prime * result + monitor.hashCode();
return result;
}
@Override
public boolean equals( Object obj )
{
if ( this == obj )
return true;
if ( obj == null )
return false;
if ( getClass() != obj.getClass() )
return false;
HudsonJob other = (HudsonJob) obj;
if ( !jobId.equals( other.jobId ) )
return false;
if ( !monitor.equals( other.monitor ) )
return false;
return true;
}
@Override
{
return getServerName() + "/job/" + getJobName();
}
{
return builds;
}
assert Display.getCurrent() == null;
if (details != null && details.getLastBuild().getNumber() == number) {
return details.getLastBuild();
}
List<BuildDTO> blds = builds;
if (blds != null) {
for (BuildDTO b : blds) {
if (b.getNumber() == number) {
return b;
}
}
}
BuildDTO b = monitor.retrieveBuild( this, number );
if (b != null) {
return b;
}
return null;
}
{
buildState = result;
if (result == State.STATE_FAILED) {
return;
}
if ( this.builds != null )
{
Map<Integer, BuildDTO> numbers = new HashMap<Integer, BuildDTO>();
for ( BuildDTO b : this.builds )
numbers.put( new Integer( b.getNumber() ), b );
List<BuildDTO> reversed = new ArrayList<BuildDTO>( newBuilds );
Collections.reverse( reversed );
for ( BuildDTO b : reversed )
{
BuildDTO old = numbers.remove( new Integer( b.getNumber() ) );
boolean exists = old != null;
if ( !exists )
{
this.builds.add( 0, b );
}
if ( exists && old.getState() != BuildStateDTO.COMPLETED )
{
int index = builds.indexOf( old );
builds.add( index, b );
builds.remove( old );
}
}
for ( BuildDTO b : numbers.values() )
{
this.builds.remove( b );
}
}
else
{
this.builds = new ArrayList<BuildDTO>( newBuilds != null ? newBuilds : Collections.<BuildDTO>emptyList());
}
}
{
return buildState == State.STATE_OK;
}
{
return changes.get( new Integer( build.getNumber() ) );
}
{
return changes.containsKey( new Integer( build.getNumber() ) );
}
{
this.changes.put( new Integer( number ), changes );
}
public TestsDTO
getTests( BuildDTO build )
throws Exception
{
assert Display.getCurrent() == null;
return monitor.getTests( this, build );
}
{
assert Display.getCurrent() == null;
return monitor.getConsoleInfo( this, build );
}
public InputStream
getConsoleContent( BuildDTO build, Long beginning, Long end )
throws Exception
{
assert Display.getCurrent() == null;
return monitor.getConsoleContent( this, build, beginning, end );
}
{
synchronized ( listeners )
{
if ( listeners.size() == 0 )
{
monitor.addHudsonJobListener( monitorListener );
}
listeners.add( listener );
}
}
{
synchronized ( listeners )
{
listeners.remove( listener );
if ( listeners.size() == 0 )
{
monitor.removeHudsonJobListener( monitorListener );
}
}
}
private void refireEvent( AbstractHudsonJobEvent event )
{
List<HudsonJobListener> lists = new ArrayList<HudsonJobListener>();
synchronized ( listeners )
{
lists.addAll( listeners );
}
for ( HudsonJobListener list : lists )
{
list.getModified( event );
}
}
{
if (details != null) {
return details.getRef();
}
return null;
}
{
assert Display.getCurrent() == null;
HudsonJob toRet = null;
if (detailsState == State.STATE_NOT_LOADED || detailsState == State.STATE_DIRTY) {
refresh( false, true );
}
ProjectDTO details = getJobDetails();
if (details != null) {
ProjectReferenceDTO ref = details.getParent();
if (ref != null) {
toRet = monitor.hudsonJobForReference( ref );
}
}
return toRet;
}
}