View Javadoc

1   package org.apache.onami.converters.i18n;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.text.DateFormat;
23  import java.text.ParsePosition;
24  import java.text.SimpleDateFormat;
25  import java.util.ArrayList;
26  import java.util.Calendar;
27  import java.util.Date;
28  import java.util.List;
29  import java.util.Locale;
30  import java.util.TimeZone;
31  
32  import org.apache.onami.converters.core.AbstractConverter;
33  import org.kohsuke.MetaInfServices;
34  
35  import com.google.inject.Module;
36  import com.google.inject.TypeLiteral;
37  
38  /**
39   * Converter implementation for {@code java.util.Calendar} and {@code java.util.Date}.
40   */
41  @MetaInfServices( Module.class )
42  public final class DateConverter
43      extends AbstractConverter<Date>
44  {
45  
46      private final List<String> patterns = new ArrayList<String>();
47  
48      private Locale locale;
49  
50      private TimeZone timeZone;
51  
52      public DateConverter()
53      {
54          // ISO date formats
55          addPattern( "yyyy" );
56          addPattern( "yyyy-MM" );
57          addPattern( "yyyy-MM-dd" );
58          addPattern( "yyyy-MM-dd'T'hh:mmZ" );
59          addPattern( "yyyy-MM-dd'T'hh:mm:ssZ" );
60          addPattern( "yyyy-MM-dd'T'hh:mm:ss.sZ" );
61      }
62  
63      public void setLocale( Locale locale )
64      {
65          this.locale = locale;
66      }
67  
68      public void setTimeZone( TimeZone timeZone )
69      {
70          this.timeZone = timeZone;
71      }
72  
73      public void addPattern( String pattern )
74      {
75          this.patterns.add( pattern );
76      }
77  
78      /**
79       * {@inheritDoc}
80       */
81      public Object convert( String value, TypeLiteral<?> toType )
82      {
83          Exception firstEx = null;
84          for ( String pattern : patterns )
85          {
86              try
87              {
88                  DateFormat format;
89                  if ( locale != null )
90                  {
91                      format = new SimpleDateFormat( pattern, locale );
92                  }
93                  else
94                  {
95                      format = new SimpleDateFormat( pattern );
96                  }
97                  if ( timeZone != null )
98                  {
99                      format.setTimeZone( timeZone );
100                 }
101                 format.setLenient( false );
102                 Date date = parse( value, format );
103 
104                 if ( Calendar.class == toType.getType() )
105                 {
106                     Calendar calendar = null;
107                     if ( locale == null && timeZone == null )
108                     {
109                         calendar = Calendar.getInstance();
110                     }
111                     else if ( locale == null )
112                     {
113                         calendar = Calendar.getInstance( timeZone );
114                     }
115                     else if ( timeZone == null )
116                     {
117                         calendar = Calendar.getInstance( locale );
118                     }
119                     else
120                     {
121                         calendar = Calendar.getInstance( timeZone, locale );
122                     }
123                     calendar.setTime( date );
124                     calendar.setLenient( false );
125                     return calendar;
126                 }
127 
128                 return date;
129             }
130             catch ( RuntimeException ex )
131             {
132                 if ( firstEx == null )
133                 {
134                     firstEx = ex;
135                 }
136             }
137         }
138 
139         throw new IllegalArgumentException( "Error converting '"
140                                             + value
141                                             + "' using  patterns "
142                                             + patterns,
143                                             firstEx );
144     }
145 
146     private Date parse( String value, DateFormat format )
147     {
148         ParsePosition pos = new ParsePosition( 0 );
149         Date parsedDate = format.parse( value, pos ); // ignore the result (use the Calendar)
150 
151         if ( pos.getErrorIndex() >= 0 || pos.getIndex() != value.length() || parsedDate == null )
152         {
153             String msg = "Error converting '" + value + "'";
154             if ( format instanceof SimpleDateFormat )
155             {
156                 msg += " using pattern '" + ( (SimpleDateFormat) format ).toPattern() + "'";
157             }
158             throw new IllegalArgumentException( msg );
159         }
160 
161         return parsedDate;
162     }
163 
164 }