001/* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2013 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * SonarQube is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020 021package org.sonar.api.utils.internal; 022 023import com.google.common.annotations.VisibleForTesting; 024import org.apache.commons.lang.builder.ToStringBuilder; 025import org.apache.commons.lang.builder.ToStringStyle; 026 027import javax.annotation.Nullable; 028 029import java.io.Serializable; 030 031/** 032 * Please do not use this class, it will be refactored in 4.3 033 * 034 * @since 4.2 035 */ 036public class WorkDuration implements Serializable { 037 038 static final int DAY_POSITION_IN_LONG = 10000; 039 static final int HOUR_POSITION_IN_LONG = 100; 040 static final int MINUTE_POSITION_IN_LONG = 1; 041 042 public static enum UNIT { 043 DAYS, HOURS, MINUTES 044 } 045 046 private int hoursInDay; 047 048 private long durationInSeconds; 049 private int days; 050 private int hours; 051 private int minutes; 052 053 private WorkDuration(long durationInSeconds, int days, int hours, int minutes, int hoursInDay) { 054 this.durationInSeconds = durationInSeconds; 055 this.days = days; 056 this.hours = hours; 057 this.minutes = minutes; 058 this.hoursInDay = hoursInDay; 059 } 060 061 public static WorkDuration create(int days, int hours, int minutes, int hoursInDay) { 062 long durationInSeconds = 3600L * days * hoursInDay; 063 durationInSeconds += 3600L * hours; 064 durationInSeconds += 60L * minutes; 065 return new WorkDuration(durationInSeconds, days, hours, minutes, hoursInDay); 066 } 067 068 public static WorkDuration createFromValueAndUnit(int value, UNIT unit, int hoursInDay) { 069 switch (unit) { 070 case DAYS: 071 return create(value, 0, 0, hoursInDay); 072 case HOURS: 073 return create(0, value, 0, hoursInDay); 074 case MINUTES: 075 return create(0, 0, value, hoursInDay); 076 default: 077 throw new IllegalStateException("Cannot create work duration"); 078 } 079 } 080 081 static WorkDuration createFromLong(long duration, int hoursInDay) { 082 int days = 0, hours = 0, minutes = 0; 083 084 long time = duration; 085 Long currentTime = time / WorkDuration.DAY_POSITION_IN_LONG; 086 if (currentTime > 0) { 087 days = (currentTime.intValue()); 088 time = time - (currentTime * WorkDuration.DAY_POSITION_IN_LONG); 089 } 090 091 currentTime = time / WorkDuration.HOUR_POSITION_IN_LONG; 092 if (currentTime > 0) { 093 hours = currentTime.intValue(); 094 time = time - (currentTime * WorkDuration.HOUR_POSITION_IN_LONG); 095 } 096 097 currentTime = time / WorkDuration.MINUTE_POSITION_IN_LONG; 098 if (currentTime > 0) { 099 minutes = currentTime.intValue(); 100 } 101 return WorkDuration.create(days, hours, minutes, hoursInDay); 102 } 103 104 static WorkDuration createFromSeconds(long seconds, int hoursInDay) { 105 int days = (int) (seconds / hoursInDay / 60f / 60f); 106 long currentDurationInSeconds = seconds - (3600L * days * hoursInDay); 107 int hours = (int) (currentDurationInSeconds / 60f / 60f); 108 currentDurationInSeconds = currentDurationInSeconds - (3600L * hours); 109 int minutes = (int) (currentDurationInSeconds / 60f); 110 return new WorkDuration(seconds, days, hours, minutes, hoursInDay); 111 } 112 113 /** 114 * Return the duration in number of working days. 115 * For instance, 3 days and 4 hours will return 3.5 days (if hoursIndDay is 8). 116 */ 117 public double toWorkingDays() { 118 return durationInSeconds / 60d / 60d / hoursInDay; 119 } 120 121 /** 122 * Return the duration using the following format DDHHMM, where DD is the number of days, HH is the number of months, and MM the number of minutes. 123 * For instance, 3 days and 4 hours will return 030400 (if hoursIndDay is 8). 124 */ 125 public long toLong() { 126 int workingDays = days; 127 int workingHours = hours; 128 if (hours >= hoursInDay) { 129 int nbAdditionalDays = hours / hoursInDay; 130 workingDays += nbAdditionalDays; 131 workingHours = hours - (nbAdditionalDays * hoursInDay); 132 } 133 return workingDays * DAY_POSITION_IN_LONG + workingHours * HOUR_POSITION_IN_LONG + minutes * MINUTE_POSITION_IN_LONG; 134 } 135 136 public long toSeconds() { 137 return durationInSeconds; 138 } 139 140 public WorkDuration add(@Nullable WorkDuration with) { 141 if (with != null) { 142 return WorkDuration.createFromSeconds(this.toSeconds() + with.toSeconds(), this.hoursInDay); 143 } else { 144 return this; 145 } 146 } 147 148 public WorkDuration subtract(@Nullable WorkDuration with) { 149 if (with != null) { 150 return WorkDuration.createFromSeconds(this.toSeconds() - with.toSeconds(), this.hoursInDay); 151 } else { 152 return this; 153 } 154 } 155 156 public WorkDuration multiply(int factor) { 157 return WorkDuration.createFromSeconds(this.toSeconds() * factor, this.hoursInDay); 158 } 159 160 public int days() { 161 return days; 162 } 163 164 public int hours() { 165 return hours; 166 } 167 168 public int minutes() { 169 return minutes; 170 } 171 172 @VisibleForTesting 173 int hoursInDay() { 174 return hoursInDay; 175 } 176 177 @Override 178 public boolean equals(Object o) { 179 if (this == o) { 180 return true; 181 } 182 if (o == null || getClass() != o.getClass()) { 183 return false; 184 } 185 186 WorkDuration that = (WorkDuration) o; 187 if (durationInSeconds != that.durationInSeconds) { 188 return false; 189 } 190 191 return true; 192 } 193 194 @Override 195 public int hashCode() { 196 return (int) (durationInSeconds ^ (durationInSeconds >>> 32)); 197 } 198 199 @Override 200 public String toString() { 201 return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); 202 } 203}