View Javadoc

1   package net.stff.ical.beans;
2   
3   import java.util.Calendar;
4   import java.util.Date;
5   import java.util.Iterator;
6   import java.util.LinkedList;
7   import java.util.List;
8   import java.util.TreeSet;
9   import java.util.Vector;
10  
11  /***
12   *  Stores calendar data for templating
13   *
14   *@author     buntekuh
15   *@created    9. Juni 2003
16   */
17  public class CalendarDay{
18  	public static String TODAY = "calToday";
19  	public static String ANOTHERMONTH = "calanothermonth";
20  	public static String THISMONTH = "calthismonth";
21  	String type;
22  	int day;
23  	int countingDays;
24  	List events;
25  	List alldayEvents;
26  	Calendar today;
27  	protected Object[][] timetable;	//two dimensional array of int
28  	protected int[] dimensions= new int[2];	//dimensions of timetable
29  
30  	public CalendarDay(){
31  	}
32  
33  	public CalendarDay(String type, int day, int countingDays, Calendar today){
34  		this.type = type;
35  		this.day = day;
36  		this.countingDays = countingDays;
37  		this.today= IEvent.getStartOfDay(today.getTime());
38  	}
39  
40      /***
41       * @return Returns the today.
42       */
43      public Calendar getToday() {
44          return today;
45      }
46      /***
47       * @param today The today to set.
48       */
49      public void setToday(Calendar today) {
50          this.today = today;
51      }
52  	public void setType(String type){
53  		this.type = type;
54  	}
55  
56  	public void setDay(int day){
57  		this.day = day;
58  	}
59  
60  	public void setEvents(List events){
61  		this.events = events;
62  	}
63  	
64      /***
65       * @return Returns the alldayEvents.
66       */
67      public List getAlldayEvents() {
68          return alldayEvents;
69      }
70      /***
71       * @param alldayEvents The alldayEvents to set.
72       */
73      public void setAlldayEvents(List alldayEvents) {
74          this.alldayEvents = alldayEvents;
75      }
76  	/***
77  	 * Sorts the given events into a timetable.<br>
78  	 * Please @see setSortedEvents() and @see scheduleEvents() for further information
79  	 * @param events
80  	 * @param start
81  	 * @param iterations
82  	 * @param resolution
83  	 */
84  	public void schedule(List events, Calendar start, int iterations, int resolution){
85  	    setSortedEvents(events);
86  	    scheduleEvents(start, iterations, resolution);
87  	}
88  	/***
89  	 * This methods adds and sorts the supplied events into a list which in turn contains other lists.<br> 
90  	 * A single list will contain events sorted chronologically. If two or more events collide, the additional events are moved to second or nth list.
91  	 * @param events The events to add and sort
92  	 */
93  	private void setSortedEvents(List events){
94  		this.events= new Vector(); 
95  	    TreeSet set= new TreeSet(events);
96  	    
97  	    Calendar cal= IEvent.getStartOfDay(new Date());
98  	    Calendar thisCal= (Calendar)cal.clone();
99  	    
100 	    Iterator i= set.iterator();
101 	    while (i.hasNext()){
102 	        IEvent e= (IEvent)i.next();
103 	        cal.set(Calendar.HOUR_OF_DAY, e.getStartHour());
104 	        cal.set(Calendar.MINUTE, e.getStartMinute());
105 	        
106 	        Iterator ei= this.events.iterator();
107 	        boolean added= false;
108 	        while (ei.hasNext()){
109 	            LinkedList l= (LinkedList)ei.next();
110 	            IEvent thisEvent= (IEvent)l.getLast();
111 	            thisCal.set(Calendar.HOUR_OF_DAY, thisEvent.getEndHour());
112 	            thisCal.set(Calendar.MINUTE, thisEvent.getEndMinute());
113 	            
114 	            //System.out.println(thisEvent.getDtend()+"...."+e.getDtstart());
115 	            if (thisCal.getTime().before(cal.getTime())){
116 	                l.add(e);
117 	                added= true;
118 	                break;
119 	            }
120 	        }
121 	        if (!added){
122 	            List l= new LinkedList();
123 	            l.add(e);
124 	            this.events.add(l);
125 	        }
126 	        
127 	    }
128 	    /*
129 	    Iterator ii= this.events.iterator();
130 	    while (ii.hasNext()){
131 	        LinkedList l= (LinkedList)ii.next();
132 		    Iterator iii= l.iterator();
133 		    while (iii.hasNext()){
134 		        IEvent e= (IEvent)iii.next();
135 		        System.out.println(e.getSummary()+" start: "+e.getDtstartString()+" end: "+e.getDtendString());
136 		    }
137 		    System.out.println("next list");
138 	    }
139 		*/
140 	}
141 	
142 	/***
143 	 * This method will sort the events into a 2 dimensional integer array. Each row represents a time period. 
144 	 * If an Event takes place at that time it will be added anywhere on this row. 
145 	 * only valid after calling setSortedEvents(). 
146 	 * @param start The Hour and Minute the first period shall start.
147 	 * @param iterations The number of periods to iterate over.
148 	 * @param resolution the time in Minutes the period should last.
149 	 */
150 	private void scheduleEvents(Calendar s, int iterations, int resolution){
151 	    
152 	    if ((events == null) || (events.size() == 0)) return;
153 	    dimensions[0]= iterations;
154 	    dimensions[1]= events.size();
155 	    timetable= new Object[iterations][events.size()];
156 
157 	    Calendar es= Calendar.getInstance();
158 	    Calendar ee= Calendar.getInstance();
159 	    s.setLenient(true);
160 
161 	    //s.add(Calendar.MILLISECOND, -1);
162 	    Calendar e= (Calendar)s.clone();
163 	    e.add(Calendar.MINUTE, resolution);
164 	    
165 	    for(int n=0;n<iterations;n++){
166 	        
167 	        for(int m=0;m<events.size();m++){
168 	            LinkedList column= (LinkedList)events.get(m);
169 	            if (column.size() == 0) continue;
170 	            IEvent ev= (IEvent)column.getFirst();
171 	            es.setTime(ev.getDtstart());
172 	            es.set(Calendar.DATE, s.get(Calendar.DATE));
173 	            es.set(Calendar.MONTH, s.get(Calendar.MONTH));
174 	            es.set(Calendar.YEAR, s.get(Calendar.YEAR));
175 	            es.add(Calendar.MILLISECOND, 1); //to prevent an equal, the event starts a millisecond later
176 
177 	            ee.setTime(ev.getDtend());
178 	            ee.set(Calendar.DATE, s.get(Calendar.DATE));
179 	            ee.set(Calendar.MONTH, s.get(Calendar.MONTH));
180 	            ee.set(Calendar.YEAR, s.get(Calendar.YEAR));
181 	            ee.add(Calendar.MILLISECOND, -1);
182 	            
183 	            //System.out.println("Event start:"+es.getTime()+"; end:"+ee.getTime());
184 	            //System.out.println("      start:"+s.getTime()+"; end:"+e.getTime());
185 	            
186 	            if (ev.getDuration() == 0){
187 	                //not yet started
188 	                if ((es.getTime().after(s.getTime())) && (es.getTime().before(e.getTime()))){
189 		                //start now
190 		                //System.out.println("start now...");
191 		                timetable[n][m]= ev;
192 		                ev.endure();
193 		                if (ee.getTime().before(e.getTime())){
194 		                    //event might start and end at the same time;
195 		                    column.removeFirst();
196 		                }
197 	                }
198 	                else{
199 	                    timetable[n][m]= null;
200 	                    //System.out.println("null");
201 	                }
202 	            }
203 	            else {
204 	                //started already
205 	                if (ee.getTime().after(e.getTime())){
206 		        		//persist
207 		                //System.out.println("...persist...");
208 		        	    timetable[n][m]= "persist";
209 		        	    ev.endure();
210 	                }
211 	                else{
212 		        		//end now
213 		                //System.out.println("...end now");
214 		        	    timetable[n][m]= "persist";
215 	        	        ev.endure();
216 		        		column.removeFirst();
217 	                }
218 	            }	            	            
219 	        }
220 		    s.add(Calendar.MINUTE, resolution);
221 		    e.add(Calendar.MINUTE, resolution);	        
222 	    }
223 	}
224 	
225 	public void addEvent(VEvent event){
226 	    events.add(event);
227 	}
228 
229 	public String getType(){
230 		return type;
231 	}
232 
233 	public int getDay(){
234 		return day;
235 	}
236 
237 	public void setCountingDays(int countingDays){
238 		this.countingDays = countingDays;
239 	}
240 	
241 	public int getSize(){
242 	    if (events == null) return -1;
243 	    return events.size();
244 	}
245 
246 	public int getAlldaySize(){
247 	    if (alldayEvents == null) return -1;
248 	    return alldayEvents.size();
249 	}
250 	public int getCountingDays(){
251 		return countingDays;
252 	}
253 
254 	public List getEvents(){
255 		return events;
256 	}
257 	
258 	
259 	private class Persist extends Vector{
260 		
261 		public boolean persists(Date d){
262 			IEvent ev= (IEvent)this.get(this.size()-1);
263 			if ((ev.dtstart.before(d)) && (ev.dtend.after(d))) return true;
264 			return false;
265 		}
266 	}
267     /***
268      * @return Returns the timetable.
269      */
270     public Object[][] getTimetable() {
271         return timetable;
272     }
273     /***
274      * @return Returns the dimensions.
275      */
276     public int[] getDimensions() {
277         return dimensions;
278     }
279 }