/*************************GO-LICENSE-START*********************************
* Copyright 2014 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*************************GO-LICENSE-END***********************************/
package com.thoughtworks.go.presentation.pipelinehistory;
import com.thoughtworks.go.config.CaseInsensitiveString;
import com.thoughtworks.go.config.MingleConfig;
import com.thoughtworks.go.config.TrackingTool;
import com.thoughtworks.go.config.materials.MaterialConfigs;
import com.thoughtworks.go.config.materials.dependency.DependencyMaterialConfig;
import com.thoughtworks.go.domain.*;
import com.thoughtworks.go.domain.buildcause.BuildCause;
import com.thoughtworks.go.domain.materials.MaterialConfig;
import com.thoughtworks.go.domain.materials.Revision;
import com.thoughtworks.go.util.TimeConverter;
import java.util.Date;
public class PipelineInstanceModel implements PipelineInfo {
private long id;
private String name;
private String label;
private BuildCause buildCause;
private StageInstanceModels stageHistory;
protected boolean canRun;
private Integer counter;
private MaterialRevisions latest = new MaterialRevisions();
private MaterialConfigs materialConfigs = new MaterialConfigs();
protected boolean isPreparingToSchedule;
private PipelineTimelineEntry pipelineAfter;
private PipelineTimelineEntry pipelineBefore;
private boolean canUnlock;
private boolean lockable;
private double naturalOrder;
private int previousPipelineCounter;
private String previousPipelineLabel;
private boolean isCurrentlyLocked;
private TrackingTool trackingTool;
private MingleConfig mingleConfig;
private String comment;
private PipelineInstanceModel() {
stageHistory = new StageInstanceModels();
}
public PipelineInstanceModel(String name, Integer counter, String label, BuildCause buildCause, StageInstanceModels stageHistory) {
this.name = name;
this.counter = counter;
this.label = label;
this.buildCause = buildCause;
this.stageHistory = stageHistory;
}
public boolean hasHistoricalData() {
return true;
}
public BuildCause getBuildCause() {
return buildCause;
}
public void setBuildCause(BuildCause buildCause) {
this.buildCause = buildCause;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public String getUri() {
return "/" + name + "/" + label;
}
public String getBuildCauseMessage() {
return buildCause == null ? "Unknown" : buildCause.getBuildCauseMessage();
}
public boolean hasStageBeenRun(String stageName) {
return stageHistory.hasStage(stageName);
}
public String nextStageName(String stageName) {
return stageHistory.nextStageName(stageName);
}
public void setName(String name) {
this.name = name;
}
public StageInstanceModels getStageHistory() {
return stageHistory;
}
public String getBuildCauseBy() {
return buildCause.getBuildCauseMessage();
}
public void setStageHistory(StageInstanceModels stageHistory) {
this.stageHistory = stageHistory;
}
public Date getScheduledDate() {
return stageHistory == null ? null : stageHistory.getScheduledDate();
}
public TimeConverter.ConvertedTime getCreatedTimeForDisplay() {
return TimeConverter.convertHandleNull(getScheduledDate());
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public boolean isAnyStageActive() {
for (StageInstanceModel stage : stageHistory) {
if (stage.getState().isActive()) {
return true;
}
}
return false;
}
public boolean hasPreviousStageBeenScheduled(String stageName) {
StageInstanceModel stage = stageHistory.byName(stageName);
int index = stageHistory.indexOf(stage);
if (index == 0) {
return true;
}
if (index > 0) {
return stageHistory.get(index - 1).isScheduled();
}
return false;
}
public void selectStage(String selectedStageName) {
StageInstanceModel stage = stageHistory.byName(selectedStageName);
if (stage != null && stage.isScheduled()) {
stage.setSelected(true);
}
}
public boolean isScheduled() {
for (StageInstanceModel stageInstanceModel : stageHistory) {
if (stageInstanceModel.isScheduled()) { return true; }
}
return false;
}
public void setCanRun(boolean canRun) {
this.canRun = canRun;
}
public boolean getCanRun() {
return canRun;
}
public String getRevisionOfLatestModification() {
return buildCause.getMaterialRevisions().latestRevision();
}
public Integer getCounter() {
return counter;
}
public void setCounter(Integer counter) {
this.counter = counter;
}
public PipelineIdentifier getPipelineIdentifier() {
return new PipelineIdentifier(name, counter, label);
}
public void setMaterialRevisionsOnBuildCause(MaterialRevisions materialRevisions) {
buildCause.setMaterialRevisions(materialRevisions);
}
public MaterialRevisions getCurrentRevisions() {
return buildCause.getMaterialRevisions();
}
public MaterialRevisions getLatestRevisions() {
return latest;
}
public MaterialConfigs getMaterials() {
return materialConfigs;
}
public Revision getLatestRevision(MaterialConfig materialConfig) {
return revisionFor(getLatestMaterialRevision(materialConfig));
}
private Revision revisionFor(MaterialRevision materialRevision) {
return materialRevision.hasModifications() ? materialRevision.getRevision() : UNKNOWN_REVISION;
}
public MaterialRevision getLatestMaterialRevision(MaterialConfig materialConfig) {
return findMaterialRevisionOf(materialConfig, latest);
}
public Revision getCurrentRevision(MaterialConfig materialConfig) {
return revisionFor(findMaterialRevisionOf(materialConfig, buildCause.getMaterialRevisions()));
}
private MaterialRevision findMaterialRevisionOf(MaterialConfig materialConfig, MaterialRevisions materialRevisions) {
for (MaterialRevision materialRevision : materialRevisions) {
if (materialRevision.getMaterial().hasSameFingerprint(materialConfig)) {
return materialRevision;
}
}
return new NullMaterialRevision();
}
public MaterialRevision findCurrentMaterialRevisionForUI(MaterialConfig materialConfig) {
MaterialRevision materialRevision = findCurrentMaterialRevisionUsingPipelineUniqueFingerprint(materialConfig);
if (materialRevision == null) {
materialRevision = findCurrentMaterialRevisionUsingFingerprint(materialConfig);
}
return materialRevision;
}
private MaterialRevision findCurrentMaterialRevisionUsingFingerprint(MaterialConfig materialConfig) {
for (MaterialRevision materialRevision : buildCause.getMaterialRevisions()) {
if (materialRevision.getMaterial().hasSameFingerprint(materialConfig)) {
return materialRevision;
}
}
return null;
}
private MaterialRevision findCurrentMaterialRevisionUsingPipelineUniqueFingerprint(MaterialConfig materialConfig) {
for (MaterialRevision materialRevision : buildCause.getMaterialRevisions()) {
if (materialRevision.getMaterial().getPipelineUniqueFingerprint().equals(materialConfig.getPipelineUniqueFingerprint())) {
return materialRevision;
}
}
return null;
}
public void setLatestRevisions(MaterialRevisions latest) {
this.latest = latest;
}
public void setMaterialConfigs(MaterialConfigs materialConfigs) {
this.materialConfigs = materialConfigs;
}
public boolean hasModificationsFor(MaterialConfig materialConfig) {
return getLatestRevision(materialConfig).isRealRevision();
}
public Revision getCurrentRevision(String requestedMaterialName) {
for (MaterialRevision materialRevision : getCurrentRevisions()) {
String materialName = CaseInsensitiveString.str(materialRevision.getMaterial().getName());
if(materialName != null && materialName.equals(requestedMaterialName)) {
return materialRevision.getRevision();
}
}
throw new RuntimeException("material not known for pipeline " + getName());
}
public String getApprovedBy() {
return getStageHistory().first().getApprovedBy();
}
public Boolean isLatestStageUnsuccessful() {
return stageHistory.isLatestStageUnsuccessful();
}
public Boolean isLatestStageSuccessful() {
return stageHistory.isLatestStageSuccessful();
}
public StageInstanceModel latestStage() {
return stageHistory.latestStage();
}
public int indexOf(StageInstanceModel stageInstanceModel) {
return stageHistory.indexOf(stageInstanceModel);
}
public int numberOfStages() {
return stageHistory.size();
}
public Boolean isRunning() {
for (StageInstanceModel model : stageHistory) {
if (model instanceof NullStageHistoryItem || model.isRunning()) {
return true;
}
}
return false;
}
public boolean hasNeverCheckedForRevisions() {
return latest.isEmpty();
}
public boolean hasNewRevisions() {
for (MaterialConfig materialConfig : materialConfigs) {
if (hasNewRevisions(materialConfig)) { return true; }
}
return false;
}
public boolean hasNewRevisions(MaterialConfig materialConfig) {
Revision currentRevision = getCurrentRevision(materialConfig);
Revision revision = getLatestRevision(materialConfig);
return !currentRevision.equals(revision);
}
public boolean isPreparingToSchedule() {
return isPreparingToSchedule;
}
public String getPipelineStatusMessage() {
StageInstanceModel latestStage = stageHistory.latestStage();
return String.format("%s: %s", latestStage.getState(), latestStage.getName());
}
/**
* @depracated use the other construction methods
*/
public static PipelineInstanceModel createEmptyModel() {
return new PipelineInstanceModel();
}
public static PipelineInstanceModel createPreparingToSchedule(String name, StageInstanceModels stages) {
return new PreparingToScheduleInstance(name, stages);
}
public static PipelineInstanceModel createPipeline(String name, Integer counter, String label, BuildCause buildCause, StageInstanceModels stageHistory) {
return new PipelineInstanceModel(name, counter, label, buildCause, stageHistory);
}
public static EmptyPipelineInstanceModel createEmptyPipelineInstanceModel(String pipelineName, BuildCause withEmptyModifications, StageInstanceModels stageHistory) {
return new EmptyPipelineInstanceModel(pipelineName, withEmptyModifications, stageHistory);
}
public boolean isLatestStage(StageInstanceModel stage) {
return stageHistory.isLatestStage(stage);
}
public PipelineTimelineEntry getPipelineBefore() {
return pipelineBefore;
}
public PipelineTimelineEntry getPipelineAfter() {
return pipelineAfter;
}
public void setPipelineAfter(PipelineTimelineEntry pipelineAfter) {
this.pipelineAfter = pipelineAfter;
}
public void setPipelineBefore(PipelineTimelineEntry pipelineBefore) {
this.pipelineBefore = pipelineBefore;
}
public boolean canUnlock() {
return canUnlock;
}
public void setCanUnlock(boolean canUnlock) {
this.canUnlock = canUnlock;
}
public boolean isLockable() {
return lockable;
}
public void setIsLockable(boolean isLockable) {
this.lockable = isLockable;
}
public StageInstanceModel activeStage() {
for (StageInstanceModel stageInstanceModel : stageHistory) {
if (stageInstanceModel.getState().isActive()) return stageInstanceModel;
}
return null;
}
public void setNaturalOrder(double naturalOrder) {
this.naturalOrder = naturalOrder;
}
public double getNaturalOrder() {
return naturalOrder;
}
public static final Revision UNKNOWN_REVISION = new Revision() {
public static final String NO_HISTORICAL_DATA = "No historical data";
public String getRevision() {
return NO_HISTORICAL_DATA;
}
public String getRevisionUrl() {
return NO_HISTORICAL_DATA;
}
public boolean isRealRevision() {
return false;
}
};
public StageInstanceModel stage(String stageName) {
return getStageHistory().byName(stageName);
}
public String getPreviousLabel() {
return previousPipelineLabel;
}
public int getPreviousCounter() {
return previousPipelineCounter;
}
public void setPreviousPipelineCounter(int counter) {
this.previousPipelineCounter = counter;
}
public void setPreviousPipelineLabel(String label) {
this.previousPipelineLabel = label;
}
public boolean hasStage(StageIdentifier identifier) {
for (StageInstanceModel instanceModel : stageHistory) {
if(identifier.equals(instanceModel.getIdentifier())) return true;
}
return false;
}
public String getApprovedByForDisplay() {
return "Triggered by " + getApprovedBy();
}
public boolean isCurrentlyLocked() {
return isCurrentlyLocked;
}
public void setCurrentlyLocked(boolean isCurrentlyLocked) {
this.isCurrentlyLocked = isCurrentlyLocked;
}
public boolean isBisect() {
double naturalOrder = this.naturalOrder;
return isBisect(naturalOrder);
}
public static boolean isBisect(double naturalOrder) {
return naturalOrder - new Double(naturalOrder).intValue() > 0;//TODO: may be we should be using long, as int can lead to truncation
}
public TrackingTool getTrackingTool() {
return trackingTool;
}
public void setTrackingTool(TrackingTool trackingTool) {
this.trackingTool = trackingTool;
}
public MingleConfig getMingleConfig() {
return mingleConfig;
}
public void setMingleConfig(MingleConfig mingleConfig) {
this.mingleConfig = mingleConfig;
}
public DependencyMaterialConfig findDependencyMaterial(CaseInsensitiveString pipelineName) {
return getMaterials().findDependencyMaterial(pipelineName);
}
public void setComment(String comment) { this.comment = comment; }
public String getComment() {
return comment;
}
}