1
18 package net.bull.javamelody.internal.model;
19
20 import java.io.IOException;
21 import java.text.SimpleDateFormat;
22 import java.util.Calendar;
23 import java.util.Date;
24 import java.util.Locale;
25
26 import net.bull.javamelody.internal.common.LOG;
27
28
32 class PeriodCounterFactory {
33
34
35
36 private final Counter currentDayCounter;
37
38 PeriodCounterFactory(Counter currentDayCounter) {
39 super();
40 assert currentDayCounter != null;
41 this.currentDayCounter = currentDayCounter;
42 }
43
44 Counter buildNewDayCounter() throws IOException {
45 final Calendar start = Calendar.getInstance();
46 start.setTime(currentDayCounter.getStartDate());
47 if (start.get(Calendar.MONTH) != Calendar.getInstance().get(Calendar.MONTH)) {
48
49
50
51 getMonthCounterAtDate(currentDayCounter.getStartDate());
52 }
53
54 return createDayCounterAtDate(new Date());
55 }
56
57
58 private Counter getDayCounterAtDate(Date day) {
59 final Counter dayCounter = createDayCounterAtDate(day);
60 try {
61 dayCounter.readFromFile();
62 } catch (final IOException e) {
63
64
65 LOG.info("read of a counter file failed: " + dayCounter.getName(), e);
66 }
67 return dayCounter;
68 }
69
70
71 Counter getCustomCounter(Range range) {
72 assert range.getPeriod() == null;
73 final Counter customCounter = createPeriodCounter("yyyy-MM-dd", range.getStartDate());
74 addRequestsAndErrorsForRange(customCounter, range);
75 return customCounter;
76 }
77
78
79 Counter getDayCounter() {
80 return currentDayCounter;
81 }
82
83
84 Counter getWeekCounter() {
85 final Counter weekCounter = createPeriodCounter("yyyyWW", currentDayCounter.getStartDate());
86 addRequestsAndErrorsForRange(weekCounter, Period.SEMAINE.getRange());
87 return weekCounter;
88 }
89
90
91
92 Counter getMonthCounter() {
93 final Counter monthCounter = createMonthCounterAtDate(currentDayCounter.getStartDate());
94 addRequestsAndErrorsForRange(monthCounter, Period.MOIS.getRange());
95 return monthCounter;
96 }
97
98 private void addRequestsAndErrorsForRange(Counter counter, Range range) {
99 final Calendar dayCalendar = Calendar.getInstance();
100 if (range.getPeriod() == null) {
101 counter.addRequestsAndErrors(getDayCounterAtDate(range.getEndDate()));
102 dayCalendar.setTime(range.getEndDate());
103
104 dayCalendar.set(Calendar.HOUR_OF_DAY, 0);
105 dayCalendar.set(Calendar.MINUTE, 0);
106 dayCalendar.set(Calendar.SECOND, 0);
107 } else {
108 counter.addRequestsAndErrors(currentDayCounter);
109 dayCalendar.setTime(currentDayCounter.getStartDate());
110 }
111 final int durationDays = range.getDurationDays();
112 for (int i = 1; i < durationDays; i++) {
113
114 dayCalendar.add(Calendar.DAY_OF_YEAR, -1);
115 counter.addRequestsAndErrors(getDayCounterAtDate(dayCalendar.getTime()));
116 }
117 counter.setStartDate(dayCalendar.getTime());
118 }
119
120
121 Counter getYearCounter() throws IOException {
122 final Counter yearCounter = createPeriodCounter("yyyy", currentDayCounter.getStartDate());
123 yearCounter.addRequestsAndErrors(currentDayCounter);
124 final Calendar dayCalendar = Calendar.getInstance();
125 final int currentMonth = dayCalendar.get(Calendar.MONTH);
126 dayCalendar.setTime(currentDayCounter.getStartDate());
127 dayCalendar.add(Calendar.DAY_OF_YEAR, -Period.ANNEE.getDurationDays() + 1);
128 yearCounter.setStartDate(dayCalendar.getTime());
129 for (int i = 1; i < Period.ANNEE.getDurationDays(); i++) {
130 if (dayCalendar.get(Calendar.DAY_OF_MONTH) == 1
131 && dayCalendar.get(Calendar.MONTH) != currentMonth) {
132
133
134 yearCounter.addRequestsAndErrors(getMonthCounterAtDate(dayCalendar.getTime()));
135 final int nbDaysInMonth = dayCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
136
137 dayCalendar.add(Calendar.DAY_OF_YEAR, nbDaysInMonth - 1);
138 i += nbDaysInMonth - 1;
139 } else {
140 yearCounter.addRequestsAndErrors(getDayCounterAtDate(dayCalendar.getTime()));
141 }
142 dayCalendar.add(Calendar.DAY_OF_YEAR, 1);
143 }
144 return yearCounter;
145 }
146
147 private Counter getMonthCounterAtDate(Date day) throws IOException {
148 final Counter monthCounter = createMonthCounterAtDate(day);
149 try {
150 final Counter readCounter = new CounterStorage(monthCounter).readFromFile();
151 if (readCounter != null) {
152
153 return readCounter;
154 }
155 } catch (final IOException e) {
156
157
158 LOG.info("read of a counter file failed: " + monthCounter.getName(), e);
159 }
160
161
162
163 final Calendar dayCalendar = Calendar.getInstance();
164 dayCalendar.setTime(day);
165 final int nbDaysInMonth = dayCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
166 for (int i = 1; i <= nbDaysInMonth; i++) {
167 dayCalendar.set(Calendar.DAY_OF_MONTH, i);
168 monthCounter.addRequestsAndErrors(getDayCounterAtDate(dayCalendar.getTime()));
169 }
170 monthCounter.writeToFile();
171 return monthCounter;
172 }
173
174 Counter createDayCounterAtDate(Date day) {
175
176
177 return createPeriodCounter("yyyyMMdd", day);
178 }
179
180 private Counter createMonthCounterAtDate(Date day) {
181
182
183 return createPeriodCounter("yyyyMM", day);
184 }
185
186 private Counter createPeriodCounter(String dateFormatPattern, Date date) {
187 final String storageName = currentDayCounter.getName() + '_'
188 + new SimpleDateFormat(dateFormatPattern, Locale.getDefault()).format(date);
189
190 final Counter result = new Counter(currentDayCounter.getName(), storageName,
191 currentDayCounter.getIconName(), currentDayCounter.getChildCounterName());
192 result.setApplication(currentDayCounter.getApplication());
193 result.setDisplayed(currentDayCounter.isDisplayed());
194 result.setRequestTransformPattern(currentDayCounter.getRequestTransformPattern());
195 result.setMaxRequestsCount(currentDayCounter.getMaxRequestsCount());
196 return result;
197 }
198 }
199