1 package org.apache.maven.continuum.web.view.jsp.ui;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.opensymphony.xwork2.ActionContext;
23 import com.opensymphony.xwork2.TextProvider;
24 import com.opensymphony.xwork2.util.ValueStack;
25
26 import java.io.IOException;
27 import java.text.SimpleDateFormat;
28 import java.util.ArrayList;
29 import java.util.Calendar;
30 import java.util.Date;
31 import java.util.List;
32
33 import javax.servlet.jsp.JspException;
34
35 import org.apache.struts2.views.jsp.ui.TextareaTag;
36
37
38
39
40
41
42
43
44
45
46
47 public class DateTag
48 extends TextareaTag
49 {
50
51
52
53
54 public final static String DATETAG_PROPERTY = "webwork.date";
55
56 public final static String DATETAG_PROPERTY_PAST = "webwork.date.format.past";
57
58 public final static String DATETAG_DEFAULT_PAST = "{0} ago";
59
60 public final static String DATETAG_PROPERTY_FUTURE = "webwork.date.format.future";
61
62 public final static String DATETAG_DEFAULT_FUTURE = "in {0}";
63
64 public final static String DATETAG_PROPERTY_SECONDS = "webwork.date.format.seconds";
65
66 public final static String DATETAG_DEFAULT_SECONDS = "an instant";
67
68 public final static String DATETAG_PROPERTY_MINUTES = "webwork.date.format.minutes";
69
70 public final static String DATETAG_DEFAULT_MINUTES = "{0,choice,1#one minute|1<{0} minutes}";
71
72 public final static String DATETAG_PROPERTY_HOURS = "webwork.date.format.hours";
73
74 public final static String DATETAG_DEFAULT_HOURS =
75 "{0,choice,1#one hour|1<{0} hours}{1,choice,0#|1#, one minute|1<, {1} minutes}";
76
77 public final static String DATETAG_PROPERTY_DAYS = "webwork.date.format.days";
78
79 public final static String DATETAG_DEFAULT_DAYS =
80 "{0,choice,1#one day|1<{0} days}{1,choice,0#|1#, one hour|1<, {1} hours}";
81
82 public final static String DATETAG_PROPERTY_YEARS = "webwork.date.format.years";
83
84 public final static String DATETAG_DEFAULT_YEARS =
85 "{0,choice,1#one year|1<{0} years}{1,choice,0#|1#, one day|1<, {1} days}";
86
87
88 private String format;
89
90 private String nameAttr;
91
92 private boolean nice;
93
94 private Date date;
95
96 private TextProvider tp;
97
98 public int doEndTag()
99 throws JspException
100 {
101 String actualName = findString( nameAttr );
102 String msg = null;
103 ValueStack stack = getStack();
104
105 Object dateObj = stack.findValue( actualName );
106
107 if ( dateObj != null )
108 {
109 if ( dateObj instanceof Date )
110 {
111 date = (Date) dateObj;
112 }
113 else if ( dateObj instanceof Long )
114 {
115 Calendar cal = Calendar.getInstance();
116 cal.setTimeInMillis( (Long) dateObj );
117 date = cal.getTime();
118 }
119 else
120 {
121 throw new JspException( "Could not cast the requested object " + nameAttr + " to a java.util.Date" );
122 }
123 }
124
125 if ( date != null && date.getTime() > 0 )
126 {
127 tp = findProviderInStack();
128
129 if ( tp == null )
130 {
131 throw new JspException( "Could not find a TextProvider on the stack." );
132 }
133
134 if ( nice )
135 {
136 msg = formatTime( date );
137 }
138 else
139 {
140 if ( format == null )
141 {
142 String globalFormat;
143
144
145
146 globalFormat = tp.getText( DATETAG_PROPERTY );
147
148 if ( globalFormat != null )
149 {
150 msg =
151 new SimpleDateFormat( globalFormat, ActionContext.getContext().getLocale() ).format( date );
152 }
153 else
154 {
155
156 }
157 }
158 else
159 {
160 msg = new SimpleDateFormat( format, ActionContext.getContext().getLocale() ).format( date );
161 }
162 }
163 }
164
165 if ( msg != null )
166 {
167 try
168 {
169
170
171
172 if ( getId() == null )
173 {
174 pageContext.getOut().write( msg );
175 }
176 else
177 {
178 stack.getContext().put( getId(), msg );
179 }
180 }
181 catch ( IOException e )
182 {
183 throw new JspException( e );
184 }
185 }
186 return EVAL_PAGE;
187 }
188
189 private TextProvider findProviderInStack()
190 {
191 for ( Object o : getStack().getRoot() )
192 {
193 if ( o instanceof TextProvider )
194 {
195 return (TextProvider) o;
196 }
197
198 }
199 return null;
200 }
201
202 public String formatTime( Date date )
203 {
204 StringBuffer sb = new StringBuffer();
205 List<Object> args = new ArrayList<Object>();
206 long secs = ( new Date().getTime() - date.getTime() ) / 1000;
207 long mins = secs / 60;
208 int min = (int) mins % 60;
209 long hours = mins / 60;
210 int hour = (int) hours % 24;
211 int days = (int) hours / 24;
212 int day = days % 365;
213 int years = days / 365;
214
215 if ( Math.abs( secs ) < 60 )
216 {
217 args.add( secs );
218 args.add( sb );
219 args.add( null );
220 sb.append( tp.getText( DATETAG_PROPERTY_SECONDS, DATETAG_DEFAULT_SECONDS, args ) );
221
222 }
223 else if ( hours == 0 )
224 {
225 args.add( (long) min );
226 args.add( sb );
227 args.add( null );
228 sb.append( tp.getText( DATETAG_PROPERTY_MINUTES, DATETAG_DEFAULT_MINUTES, args ) );
229
230 }
231 else if ( days == 0 )
232 {
233 args.add( (long) hour );
234 args.add( (long) min );
235 args.add( sb );
236 args.add( null );
237 sb.append( tp.getText( DATETAG_PROPERTY_HOURS, DATETAG_DEFAULT_HOURS, args ) );
238 }
239 else if ( years == 0 )
240 {
241 args.add( (long) days );
242 args.add( (long) hour );
243 args.add( sb );
244 args.add( null );
245 sb.append( tp.getText( DATETAG_PROPERTY_DAYS, DATETAG_DEFAULT_DAYS, args ) );
246 }
247 else
248 {
249 args.add( new Object[]{(long) years} );
250 args.add( new Object[]{(long) day} );
251 args.add( sb );
252 args.add( null );
253
254 sb.append( tp.getText( DATETAG_PROPERTY_YEARS, DATETAG_DEFAULT_YEARS, args ) );
255 }
256 args.clear();
257 args.add( sb.toString() );
258 if ( date.before( new Date() ) )
259 {
260
261 return tp.getText( DATETAG_PROPERTY_PAST, DATETAG_DEFAULT_PAST, args );
262 }
263 else
264 {
265 return tp.getText( DATETAG_PROPERTY_FUTURE, DATETAG_DEFAULT_FUTURE, args );
266 }
267 }
268
269 public void setName( String name )
270 {
271 this.nameAttr = name;
272 }
273
274 public String getFormat()
275 {
276 return format;
277 }
278
279 public void setFormat( String format )
280 {
281 this.format = format;
282 }
283
284 public boolean isNice()
285 {
286 return nice;
287 }
288
289 public void setNice( boolean nice )
290 {
291 this.nice = nice;
292 }
293 }