001: /********************************************************************************
002: * CruiseControl, a Continuous Integration Toolkit
003: * Copyright (c) 2007, ThoughtWorks, Inc.
004: * 200 E. Randolph, 25th Floor
005: * Chicago, IL 60601 USA
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * + Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * + Redistributions in binary form must reproduce the above
016: * copyright notice, this list of conditions and the following
017: * disclaimer in the documentation and/or other materials provided
018: * with the distribution.
019: *
020: * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
021: * names of its contributors may be used to endorse or promote
022: * products derived from this software without specific prior
023: * written permission.
024: *
025: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
026: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
027: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
028: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
029: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
030: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
031: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
032: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
033: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
034: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
035: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
036: ********************************************************************************/package net.sourceforge.cruisecontrol.dashboard.web.command;
037:
038: import java.util.ArrayList;
039: import java.util.Collection;
040: import java.util.HashMap;
041: import java.util.Iterator;
042: import java.util.Map;
043:
044: import net.sourceforge.cruisecontrol.Modification;
045: import net.sourceforge.cruisecontrol.dashboard.Build;
046: import net.sourceforge.cruisecontrol.dashboard.CurrentStatus;
047: import net.sourceforge.cruisecontrol.dashboard.ModificationSet;
048: import net.sourceforge.cruisecontrol.dashboard.StoryTracker;
049: import net.sourceforge.cruisecontrol.dashboard.ViewableStatusHelper;
050: import net.sourceforge.cruisecontrol.dashboard.utils.CCDateFormatter;
051: import net.sourceforge.cruisecontrol.dashboard.web.view.JsonView;
052:
053: import org.joda.time.DateTime;
054:
055: public class BuildCommand {
056: public static final String CSS_LEVEL = "level";
057:
058: private Build build;
059:
060: private Map jsonParams = new HashMap();
061:
062: private static final int MILLI_SECOND_TO_SECOND = 1000;
063:
064: private static final int STATUS_STANDING_SECTION = 24 * 60 * 60
065: * 1000 / 8;
066:
067: private final StoryTracker storyTracker;
068:
069: public BuildCommand(Build build, StoryTracker storyTracker) {
070: this .build = build;
071: this .storyTracker = storyTracker;
072: jsonParams.put(CSS_LEVEL, "unknown");
073: }
074:
075: public Build getBuild() {
076: return this .build;
077: }
078:
079: public Collection getModifications() {
080: Collection modificationCmds = new ArrayList();
081: ModificationSet modificationSet = build.getModificationSet();
082: if (modificationSet != null) {
083: Collection modifications = modificationSet
084: .getModifications();
085: for (Iterator iterator = modifications.iterator(); iterator
086: .hasNext();) {
087: Modification modification = (Modification) iterator
088: .next();
089: modificationCmds.add(new ModificationCommand(
090: modification, storyTracker));
091: }
092: }
093: return modificationCmds;
094: }
095:
096: public String getDateStringInHumanBeingReadingStyle() {
097: return CCDateFormatter
098: .getDateStringInHumanBeingReadingStyle(build
099: .getBuildDate());
100: }
101:
102: public Long getElapsedTimeBuilding(DateTime date) {
103: return new Long((date.getMillis() - build.getBuildingSince()
104: .getMillis())
105: / MILLI_SECOND_TO_SECOND);
106: }
107:
108: public void updateCssLevel(Build last) {
109: jsonParams.put(CSS_LEVEL, String
110: .valueOf(statusStandingLevel(last)));
111: }
112:
113: public String getLevel() {
114: return (String) jsonParams.get(CSS_LEVEL);
115: }
116:
117: public String getDuration() {
118: return build.getDuration() == null ? "Unknown" : build
119: .getDuration();
120: }
121:
122: public Map toJsonHash() {
123: jsonParams.put("project_name", build.getProjectName());
124: jsonParams.put("latest_build_date", build.getConvertedTime());
125: jsonParams.put("current_status", build.getCurrentStatus()
126: .getStatus());
127: jsonParams.put("previous_result", build
128: .getPreviousBuildResult().getStatus());
129: if (CurrentStatus.BUILDING.equals(build.getCurrentStatus())) {
130: jsonParams.put("build_duration", build.getDuration());
131: jsonParams.put("build_time_elapsed",
132: getElapsedTimeBuilding(new DateTime()));
133: }
134: return jsonParams;
135: }
136:
137: public String toJsonString() {
138: Map info = new HashMap();
139: info.put("building_info", this .toJsonHash());
140: return new JsonView().renderJson(info);
141: }
142:
143: public String getViewableStatus() {
144: return new ViewableStatusHelper().getVmStatus(build);
145: }
146:
147: private long statusStandingLevel(Build lastSuccessful) {
148: Build baseBuild = lastSuccessful == null ? build
149: : lastSuccessful;
150: long duration = (new DateTime().getMillis() - baseBuild
151: .getBuildDate().getMillis());
152: if (duration > 0) {
153: return Math.min(duration / STATUS_STANDING_SECTION, 8);
154: } else {
155: return 0;
156: }
157: }
158: }
|