/* * Copyright 2000-2014 JetBrains s.r.o. * * 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. */ package jetbrains.buildServer.server.restcontrib.cctray.model; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import jetbrains.buildServer.ServiceLocator; import jetbrains.buildServer.serverSide.*; /** *

Java class for anonymous complex type. *

*

The following schema fragment specifies the expected content contained within this class. *

*

 * <complexType>
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}NMTOKEN" />
 *       <attribute name="activity" use="required">
 *         <simpleType>
 *           <restriction base="{http://www.w3.org/2001/XMLSchema}NMTOKEN">
 *             <enumeration value="Sleeping"/>
 *             <enumeration value="Building"/>
 *             <enumeration value="CheckingModifications"/>
 *           </restriction>
 *         </simpleType>
 *       </attribute>
 *       <attribute name="lastBuildStatus" use="required">
 *         <simpleType>
 *           <restriction base="{http://www.w3.org/2001/XMLSchema}NMTOKEN">
 *             <enumeration value="Exception"/>
 *             <enumeration value="Success"/>
 *             <enumeration value="Failure"/>
 *             <enumeration value="Unknown"/>
 *           </restriction>
 *         </simpleType>
 *       </attribute>
 *       <attribute name="lastBuildLabel" use="required" type="{http://www.w3.org/2001/XMLSchema}NMTOKEN" />
 *       <attribute name="lastBuildTime" use="required" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
 *       <attribute name="nextBuildTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
 *       <attribute name="webUrl" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
*/ @XmlType(name = "", namespace = "http://cctray") public class Project { private SBuildType myBuildType; protected ServiceLocator myServiceLocator; public Project() { } public Project(ServiceLocator serviceLocator, SBuildType buildType) { this.myServiceLocator = serviceLocator; myBuildType = buildType; } /** * Gets the value of the name property. * * @return possible object is * {@link String } */ @XmlAttribute(name = "name", required = true) @XmlJavaTypeAdapter(CollapsedStringAdapter.class) @XmlSchemaType(name = "NMTOKEN") public String getName() { return myBuildType.getFullName(); } /** * Gets the value of the activity property. * * @return possible object is * {@link String } */ @XmlAttribute(name = "activity", required = true) @XmlJavaTypeAdapter(CollapsedStringAdapter.class) public String getActivity() { final List runningBuilds = myBuildType.getRunningBuilds(); if (runningBuilds.size() > 0) { return "Building"; } if (TeamCityProperties.getBoolean("rest.cctray.extendedActivity")) { // if (myBuildType.isInQueue()) { // return "Waiting in queue"; // non standard, makes cctray hanging // } if (myBuildType.isPaused()) { return "Paused"; // non standard } if (myBuildType.getPendingChanges().size() > 0) { return "Has pending changes"; // non standard } } return "Sleeping"; } /** * Gets the value of the lastBuildStatus property. * * @return possible object is * {@link String } */ @XmlAttribute(name = "lastBuildStatus", required = true) @XmlJavaTypeAdapter(CollapsedStringAdapter.class) public String getLastBuildStatus() { if (myBuildType.getStatus().isFailed()) { return "Failure"; } if (myBuildType.getStatus().isSuccessful()) { return "Success"; } return "Unknown"; } /** * Gets the value of the lastBuildLabel property. * * @return possible object is * {@link String } */ @XmlAttribute(name = "lastBuildLabel", required = true) @XmlJavaTypeAdapter(CollapsedStringAdapter.class) @XmlSchemaType(name = "NMTOKEN") public String getLastBuildLabel() { final SFinishedBuild lastBuild = myBuildType.getLastChangesFinished(); if (lastBuild == null) { // is this OK? return null; } return String.valueOf(lastBuild.getBuildNumber()); } /** * Gets the value of the lastBuildTime property. * * @return possible object is * {@link javax.xml.datatype.XMLGregorianCalendar } */ @XmlAttribute(name = "lastBuildTime", required = true) @XmlSchemaType(name = "dateTime") public String getLastBuildTime() { final SFinishedBuild lastBuild = myBuildType.getLastChangesFinished(); if (lastBuild == null) { // is this OK? return null; } return getFormattedTime(lastBuild.getStartDate()); } /** * Gets the value of the nextBuildTime property. * * @return possible object is * {@link javax.xml.datatype.XMLGregorianCalendar } */ @XmlAttribute(name = "nextBuildTime") @XmlSchemaType(name = "dateTime") public String getNextBuildTime() { final List queuedBuilds = myBuildType.getQueuedBuilds(null); for (SQueuedBuild build : queuedBuilds) { if (!build.isPersonal()) { final BuildEstimates estimate = build.getBuildEstimates(); if (estimate != null) { final TimeInterval interval = estimate.getTimeInterval(); if (interval != null && isValid(interval)) { return getFormattedTime(interval.getStartPoint().getAbsoluteTime()); } } } } //todo: get next VCS checking/scheduled time return null; } private String getFormattedTime(final Date date) { final String withoutTimezone = (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH)).format(date); final String timezone = (new SimpleDateFormat("Z", Locale.ENGLISH)).format(date); String modifiedTimezone = "Z"; if (timezone.length() == 5) { modifiedTimezone = timezone.substring(0, 3) + ":" + timezone.substring(3); } return withoutTimezone + modifiedTimezone; } private static boolean isValid(final TimeInterval interval) { // todo (TeamCity) can return some huge number for some reason: TW-19894 final long fromNow_ms = interval.getStartPoint().getAbsoluteTime().getTime() - (new Date()).getTime(); return 0 <= fromNow_ms && fromNow_ms <= 1000 * 60 * 60 * 24 * 100; } /** * Gets the value of the webUrl property. * * @return possible object is * {@link String } */ @XmlAttribute(name = "webUrl", required = true) public String getWebUrl() { final WebLinks webLinks = myServiceLocator.getSingletonService(WebLinks.class); return webLinks.getConfigurationHomePageUrl(myBuildType); } }