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