View Javadoc

1   package com.bradmcevoy.http;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.Calendar;
6   import java.util.Date;
7   import java.util.List;
8   
9   import org.slf4j.Logger;
10  import org.slf4j.LoggerFactory;
11  
12  public class LockTimeout implements Serializable{
13  
14      private static final long serialVersionUID = 1L;
15  
16  
17      private static Logger log = LoggerFactory.getLogger(LockTimeout.class);
18      private static final String INFINITE = "Infinite";
19      
20              
21      public static LockTimeout parseTimeout(Request request) {
22          String sTimeout = request.getTimeoutHeader();
23          log.debug("..requested timeout: " + sTimeout);
24          return parseTimeout(sTimeout);
25      }
26      
27      public static LockTimeout parseTimeout(String s) {      
28          if ( s==null ) return new LockTimeout((List<Long>)null);
29          s = s.trim();
30          if( s.length() == 0 ) return new LockTimeout((List<Long>)null);
31  
32          List<Long> list = new ArrayList<Long>();
33          for( String part : s.split(",")) {
34              part = part.trim();
35              if( part.equalsIgnoreCase(INFINITE)) {
36                  list.add(Long.MAX_VALUE);
37              } else {
38                  Long seconds = parseTimeoutPart(part);
39                  if(seconds != null ) {
40                      list.add(seconds);
41                  }
42              }
43          }
44          
45          LockTimeout timeout = new LockTimeout(list);
46          return timeout;
47      }
48  
49      static String trim(String s) {
50          if( s == null ) return "";
51          return s.trim();
52      }
53      
54      static boolean isPresent(String s) {
55          return s != null && s.length()>0;
56      }
57  
58      private static Long parseTimeoutPart(String part) {
59          if( part == null || part.length() == 0 ) return null;
60          int pos = part.indexOf("-");
61          if( pos <= 0 ) {
62              return null;
63          }
64          String s = part.substring(pos+1, part.length());
65          long l = 0;
66          try {
67              l = Long.parseLong(s);
68              return l;
69          } catch (NumberFormatException numberFormatException) {
70              log.error("Number format exception parsing timeout: " + s);
71              return null;
72          }        
73      }
74      
75      final Long seconds;
76      final Long[] otherSeconds;
77  
78      public LockTimeout(Long timeout) {
79          this.seconds = timeout;
80          this.otherSeconds = null;
81      }
82      
83      private LockTimeout(List<Long> timeouts) {
84          if( timeouts == null || timeouts.isEmpty() ) {
85              this.seconds = null;
86              this.otherSeconds = null;
87          } else {
88              this.seconds = timeouts.get(0);
89              timeouts.remove(0);
90              otherSeconds = new Long[timeouts.size()];
91              timeouts.toArray(otherSeconds);
92          }
93      }
94      
95      /**
96       * 
97       * @return - the preferred timeout. Infinite is represents as Long.MAX_VALUE. Maybe null if no timeout provided
98       */
99      public Long getSeconds() {
100         return seconds;
101     }
102 
103     /**
104      * 
105      * @return - an array of less preferred timeouts
106      */
107     public Long[] getOtherSeconds() {
108         return otherSeconds;
109     }
110 
111     @Override
112     public String toString() {
113         if( this.seconds == null ) {
114             return INFINITE;
115         } else if(this.seconds.equals( Long.MAX_VALUE )) {
116             return INFINITE;
117         } else {
118             return "Second-" + this.seconds;
119         }
120     }
121 
122 
123     
124 
125     /**
126      * Returns a current object which holds the expected end date/time, based
127      * on defaultSeconds and maxSeconds, as well as the actual seconds used
128      * in that calculation.
129      *
130      * This is handy for locking because we generally want to lock a resource
131      * until a specific date/time, but we also want to report back the timeout
132      * actually locked in terms of seconds
133      * 
134      * @return - the current time + getSeconds()
135      */
136     public DateAndSeconds getLockedUntil(Long defaultSeconds, Long maxSeconds) {
137         Long l = getSeconds();        
138         if( l == null ) {
139             if( defaultSeconds != null ) {
140                 return addSeconds(defaultSeconds);
141             } else if( maxSeconds != null ) {
142                 return addSeconds( maxSeconds);
143             } else {
144                 return addSeconds(60l); // default default
145             }
146         } else {
147             if( maxSeconds != null ) {
148                 if( getSeconds() > maxSeconds ) {
149                     return addSeconds(maxSeconds);
150                 } else {
151                     return addSeconds(l);
152                 }
153             } else {
154                 return addSeconds(l);
155             }
156         }
157     }
158     
159     public static DateAndSeconds addSeconds( Long l) {
160         Calendar cal = Calendar.getInstance();
161         cal.setTimeInMillis(System.currentTimeMillis());
162         int secs = (int)l.longValue();
163         cal.add(Calendar.SECOND, secs);
164         DateAndSeconds das = new DateAndSeconds();
165         das.date = cal.getTime();        
166         das.seconds = l;
167         return das;
168     }
169         
170     public static class DateAndSeconds {
171         public Date date;
172         public Long seconds;
173     }
174 }