You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mm...@apache.org on 2005/07/13 17:33:25 UTC

svn commit: r216175 [2/4] - in /myfaces: build/trunk/ examples/trunk/sandbox/ examples/trunk/sandbox/WEB-INF/ examples/trunk/sandbox/src/java/org/apache/myfaces/examples/schedule/ sandbox/trunk/conf/ sandbox/trunk/src/java/org/apache/myfaces/custom/sch...

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/AbstractScheduleModel.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/AbstractScheduleModel.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/AbstractScheduleModel.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/AbstractScheduleModel.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+
+/**
+ * <p>
+ * Extend this class to create your own implementation of a ScheduleModel
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public abstract class AbstractScheduleModel
+    implements ScheduleModel
+{
+    //~ Instance fields --------------------------------------------------------
+
+    protected final TreeSet days;
+    private Date selectedDate;
+    private ScheduleEntry selectedEntry;
+    private int mode;
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Creates a new AbstractScheduleModel object.
+     */
+    public AbstractScheduleModel()
+    {
+        this.days = new TreeSet();
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#isEmpty()
+     */
+    public boolean isEmpty()
+    {
+        return days.isEmpty();
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#setMode(int)
+     */
+    public void setMode(int mode)
+    {
+        this.mode = mode;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#getMode()
+     */
+    public int getMode()
+    {
+        return mode;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#setSelectedDate(java.util.Date)
+     */
+    public void setSelectedDate(Date date)
+    {
+        this.selectedDate = date;
+
+        switch (mode) {
+            case DAY:
+                setDay(date);
+
+                break;
+
+            case WORKWEEK:
+                setWorkWeek(date);
+
+                break;
+
+            case WEEK:
+                setWeek(date);
+
+                break;
+
+            case MONTH:
+                setMonth(date);
+
+                break;
+
+            default:
+                setDay(date);
+        }
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#getSelectedDate()
+     */
+    public Date getSelectedDate()
+    {
+        return selectedDate;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#setSelectedEntry(org.apache.myfaces.custom.schedule.model.ScheduleEntry)
+     */
+    public void setSelectedEntry(ScheduleEntry selectedEntry)
+    {
+        this.selectedEntry = selectedEntry;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#getSelectedEntry()
+     */
+    public ScheduleEntry getSelectedEntry()
+    {
+        return selectedEntry;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#containsDate(java.util.Date)
+     */
+    public boolean containsDate(Date date)
+    {
+        for (Iterator iterator = iterator(); iterator.hasNext();) {
+            ScheduleDay day = (ScheduleDay) iterator.next();
+
+            if (day.equalsDate(date)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#get(int)
+     */
+    public Object get(int index)
+    {
+        Object[] dayArray = days.toArray();
+
+        Object returnObject = dayArray[index];
+
+        return returnObject;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#iterator()
+     */
+    public Iterator iterator()
+    {
+        return days.iterator();
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#size()
+     */
+    public int size()
+    {
+        return days.size();
+    }
+
+    /**
+     * <p>
+     * Set the day
+     * </p>
+     *
+     * @param date the new day
+     */
+    protected void setDay(Date date)
+    {
+        clear();
+
+        if (date == null) {
+            return;
+        }
+
+        ScheduleDay day = add(date);
+        load(day.getDayStart(), day.getDayEnd());
+    }
+
+    /**
+     * <p>
+     * navigate to the specified month
+     * </p>
+     *
+     * @param date the date to navigate to
+     */
+    protected void setMonth(Date date)
+    {
+        clear();
+
+        if (date == null) {
+            return;
+        }
+
+        Calendar cal = GregorianCalendar.getInstance();
+        cal.setTime(date);
+
+        //go back to the first day of the month;
+        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DAY_OF_MONTH));
+
+        int currentMonth = cal.get(Calendar.MONTH);
+
+        ScheduleDay firstDay = null;
+        ScheduleDay lastDay = null;
+
+        while (cal.get(Calendar.MONTH) == currentMonth) {
+            ScheduleDay addedDay = add(cal.getTime());
+
+            if (firstDay == null) {
+                firstDay = addedDay;
+            }
+
+            lastDay = addedDay;
+            cal.add(Calendar.DATE, 1);
+        }
+
+        load(firstDay.getDayStart(), lastDay.getDayEnd());
+    }
+
+    /**
+     * <p>
+     * navigate to the specified week
+     * </p>
+     *
+     * @param date the date to navigate to
+     */
+    protected void setWeek(Date date)
+    {
+        clear();
+
+        if (date == null) {
+            return;
+        }
+
+        Calendar cal = GregorianCalendar.getInstance();
+        cal.setTime(date);
+
+        //go back to the monday of this week
+        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+
+        ScheduleDay firstDay = null;
+        ScheduleDay lastDay = null;
+
+        for (int i = 0; i < 7; i++) {
+            ScheduleDay addedDay = add(cal.getTime());
+
+            if (firstDay == null) {
+                firstDay = addedDay;
+            }
+
+            lastDay = addedDay;
+            cal.add(Calendar.DATE, 1);
+        }
+
+        load(firstDay.getDayStart(), lastDay.getDayEnd());
+    }
+
+    /**
+     * <p>
+     * navigate to the specified workweek
+     * </p>
+     *
+     * @param date the date to navigate to
+     */
+    protected void setWorkWeek(Date date)
+    {
+        clear();
+
+        if (date == null) {
+            return;
+        }
+
+        Calendar cal = GregorianCalendar.getInstance();
+        cal.setTime(date);
+
+        //go back to the monday of this week
+        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+
+        ScheduleDay firstDay = null;
+        ScheduleDay lastDay = null;
+
+        for (int i = 0; i < 5; i++) {
+            ScheduleDay addedDay = add(cal.getTime());
+
+            if (firstDay == null) {
+                firstDay = addedDay;
+            }
+
+            lastDay = addedDay;
+            cal.add(Calendar.DATE, 1);
+        }
+
+        load(firstDay.getDayStart(), lastDay.getDayEnd());
+    }
+
+    /**
+     * <p>
+     * Add a day to the schedule
+     * </p>
+     *
+     * @param day the day to add
+     *
+     * @return the day that was added
+     */
+    protected ScheduleDay add(Date date)
+    {
+        if (date == null) {
+            return null;
+        }
+
+        ScheduleDay day = new ScheduleDay(date);
+        loadDayAttributes(day);
+        days.add(day);
+
+        return day;
+    }
+
+    /**
+     * <p>
+     * Remove all days
+     * </p>
+     */
+    protected void clear()
+    {
+        for (Iterator dayIterator = days.iterator(); dayIterator.hasNext();) {
+            ScheduleDay day = (ScheduleDay) dayIterator.next();
+            day.clear();
+        }
+
+        days.clear();
+    }
+    
+    /**
+     * <p>
+     * This refreshes the visible days of the model
+     * </p>
+     */
+    public void refresh() {
+        setSelectedDate(selectedDate);
+    }
+
+    /**
+     * <p>
+     * Load the schedule entries that fall between the startDate and the endDate.
+     * </p>
+     *
+     * @param startDate 0 AM on the start date
+     * @param endDate 12 PM on the end date
+     */
+    protected abstract Collection loadEntries(
+        Date startDate,
+        Date endDate
+    );
+    
+    /**
+     * <p>
+     * Load any attributes for this day: is it a working day or a holiday,
+     * and what is the name of the day (e.g. "Christmas").
+     * </p>
+     * 
+     * @param day the day that should be loaded
+     */
+    protected abstract void loadDayAttributes(Day day);
+
+    private void load(
+        Date startDate,
+        Date endDate
+    )
+    {
+        Collection entries = loadEntries(startDate, endDate);
+
+        for (Iterator entryIterator = entries.iterator();
+                entryIterator.hasNext();
+        ) {
+            ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
+
+            for (Iterator dayIterator = days.iterator(); dayIterator.hasNext();) {
+                ScheduleDay day = (ScheduleDay) dayIterator.next();
+
+                day.addEntry(entry);
+            }
+        }
+    }
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/Day.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/Day.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/Day.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/Day.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+
+import java.io.Serializable;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.apache.myfaces.custom.schedule.util.ScheduleUtil;
+
+
+/**
+ * <p>
+ * This class represents a day in the Schedule component
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public class Day
+    implements Serializable, Comparable
+{
+    //~ Instance fields --------------------------------------------------------
+
+    private final Date date;
+    private final Date dayEnd;
+    private final Date dayStart;
+    private String specialDayName;
+    private boolean workingDay;
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Creates a new Day object.
+     *
+     * @param date the date
+     *
+     * @throws NullPointerException when the date is null
+     */
+    public Day(Date date)
+    {
+        super();
+        this.date = date;
+
+        if (date == null) {
+            throw new NullPointerException("date should not be null");
+        }
+
+        Calendar cal = GregorianCalendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        this.dayStart = cal.getTime();
+        cal.add(Calendar.DATE, 1);
+        this.dayEnd = cal.getTime();
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @return Returns the date.
+     */
+    public Date getDate()
+    {
+        return (date == null) ? new Date() : date;
+    }
+
+    /**
+     * @return Returns 12PM of this day
+     */
+    public Date getDayEnd()
+    {
+        return dayEnd;
+    }
+
+    /**
+     * @return Returns 0AM of this day
+     */
+    public Date getDayStart()
+    {
+        return dayStart;
+    }
+
+    /**
+     * <p>
+     * If this day is a holiday of some kind, this sets the name
+     * </p>
+     *
+     * @param specialDayName The specialDayName to set.
+     */
+    public void setSpecialDayName(String specialDayName)
+    {
+        this.specialDayName = specialDayName;
+    }
+
+    /**
+     * <p>
+     * If this day is a holiday of some kind, this gets the name
+     * </p>
+     *
+     * @return Returns the specialDayName.
+     */
+    public String getSpecialDayName()
+    {
+        return specialDayName;
+    }
+
+    /**
+     * <p>
+     * Is this day a working day?
+     * </p>
+     *
+     * @param workingDay The workingDay to set.
+     */
+    public void setWorkingDay(boolean workingDay)
+    {
+        this.workingDay = workingDay;
+    }
+
+    /**
+     * <p>
+     * Is this day a working day?
+     * </p>
+     *
+     * @return Returns the workingDay.
+     */
+    public boolean isWorkingDay()
+    {
+        Calendar cal = GregorianCalendar.getInstance();
+        cal.setTime(date);
+
+        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
+
+        if ((dayOfWeek == Calendar.SATURDAY) || (dayOfWeek == Calendar.SUNDAY)) {
+            return false;
+        }
+
+        return workingDay;
+    }
+
+    /**
+     * @see java.lang.Comparable#compareTo(java.lang.Object)
+     */
+    public int compareTo(Object o)
+    {
+        if (o instanceof Day) {
+            Day other = (Day) o;
+
+            int returnint = ScheduleUtil.compareDays(date, other.getDate());
+
+            return returnint;
+        }
+
+        return 1;
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object o)
+    {
+        if (o instanceof Day) {
+            Day other = (Day) o;
+
+            return ScheduleUtil.isSameDay(date, other.getDate());
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * Check if the specified date is on this day
+     * </p>
+     *
+     * @param date the date to check
+     *
+     * @return if the date is on this day
+     */
+    public boolean equalsDate(Date date)
+    {
+        if (date == null) {
+            return false;
+        }
+
+        return ScheduleUtil.isSameDay(date, this.date);
+    }
+
+    /**
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode()
+    {
+        return ScheduleUtil.getHashCodeForDay(date);
+    }
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/DefaultScheduleEntry.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/DefaultScheduleEntry.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/DefaultScheduleEntry.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/DefaultScheduleEntry.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+import java.io.Serializable;
+
+import java.util.Date;
+
+
+/**
+ * <p>
+ * A default implementation of a Schedule entry
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public class DefaultScheduleEntry
+    implements Serializable, ScheduleEntry
+{
+    //~ Instance fields --------------------------------------------------------
+
+    private Date endTime;
+    private Date startTime;
+    private String description;
+    private String id;
+    private String subtitle;
+    private String title;
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @param description The description to set.
+     */
+    public void setDescription(String description)
+    {
+        this.description = description;
+    }
+
+    /**
+     * @return Returns the description.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+    /**
+     * @param endTime The endTime to set.
+     */
+    public void setEndTime(Date endTime)
+    {
+        this.endTime = endTime;
+    }
+
+    /**
+     * @return Returns the endTime.
+     */
+    public Date getEndTime()
+    {
+        return endTime;
+    }
+
+    /**
+     * @param id The id to set.
+     */
+    public void setId(String id)
+    {
+        this.id = id;
+    }
+
+    /**
+     * @return Returns the id.
+     */
+    public String getId()
+    {
+        return id;
+    }
+
+    /**
+     * @param startTime The startTime to set.
+     */
+    public void setStartTime(Date startTime)
+    {
+        this.startTime = startTime;
+    }
+
+    /**
+     * @return Returns the startTime.
+     */
+    public Date getStartTime()
+    {
+        return startTime;
+    }
+
+    /**
+     * @param subtitle The subtitle to set.
+     */
+    public void setSubtitle(String subtitle)
+    {
+        this.subtitle = subtitle;
+    }
+
+    /**
+     * @return Returns the subtitle.
+     */
+    public String getSubtitle()
+    {
+        return subtitle;
+    }
+
+    /**
+     * @param title The title to set.
+     */
+    public void setTitle(String title)
+    {
+        this.title = title;
+    }
+
+    /**
+     * @return Returns the title.
+     */
+    public String getTitle()
+    {
+        return title;
+    }
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/PlannerEntity.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/PlannerEntity.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/PlannerEntity.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/PlannerEntity.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+
+import java.io.Serializable;
+
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import org.apache.myfaces.custom.schedule.util.ScheduleEntryComparator;
+
+
+/**
+ * <p>
+ * A Planner entity is a person, room, piece of equipment, ... that is displayed
+ * as a row in the planner component.
+ * </p>
+ *
+ * TODO this should be an interface, with a DefaultPlannerEntity implementation
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public class PlannerEntity
+    implements Serializable
+{
+    //~ Instance fields --------------------------------------------------------
+
+    private final String id;
+    private final String name;
+    private TreeSet entries;
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Creates a new PlannerEntity object.
+     *
+     * @param id the unique identifier
+     * @param name the name
+     */
+    public PlannerEntity(
+        String id,
+        String name
+    )
+    {
+        super();
+        this.id = id;
+        this.name = name;
+        this.entries = new TreeSet(new ScheduleEntryComparator());
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @return true if there are no appointments for this entity
+     */
+    public boolean isEmpty()
+    {
+        return entries.isEmpty();
+    }
+
+    /**
+     * @param entries The entries to set.
+     */
+    public void setEntries(TreeSet entries)
+    {
+        this.entries = entries;
+    }
+
+    /**
+     * @return Returns the entries.
+     */
+    public TreeSet getEntries()
+    {
+        return entries;
+    }
+
+    /**
+     * @return Returns the id.
+     */
+    public String getId()
+    {
+        return id;
+    }
+
+    /**
+     * @return Returns the name.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * <p>
+     * Add a schedule entry to this planner entity
+     * </p>
+     *
+     * @param entry the entry to be added
+     *
+     * @return whether the addition was successful
+     */
+    public boolean addEntry(ScheduleEntry entry)
+    {
+        if (
+            (entry == null) || (entry.getStartTime() == null) ||
+                (entry.getEndTime() == null)
+        ) {
+            return false;
+        }
+
+        entries.add(entry);
+
+        return true;
+    }
+
+    /**
+     * <p>
+     * Remove all entries
+     * </p>
+     */
+    public void clear()
+    {
+        entries.clear();
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object o)
+    {
+        if (o instanceof PlannerEntity) {
+            PlannerEntity other = (PlannerEntity) o;
+
+            return id.equals(other.id);
+        }
+
+        return false;
+    }
+
+    /**
+     * @return an iterator for the entries
+     */
+    public Iterator iterator()
+    {
+        return entries.iterator();
+    }
+
+    /**
+     * <p>
+     * Remove an entry from this entity
+     * </p>
+     *
+     * @param entry the entry to be removed
+     *
+     * @return whether the removal was successful
+     */
+    public boolean remove(ScheduleEntry entry)
+    {
+        return entries.remove(entry);
+    }
+
+    /**
+     * @return the number of entries
+     */
+    public int size()
+    {
+        return entries.size();
+    }
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/PlannerModel.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/PlannerModel.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/PlannerModel.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/PlannerModel.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+import java.io.Serializable;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+
+/**
+ * <p>
+ * The model of a Planner component
+ * </p>
+ *
+ * TODO this should be an interface, with a DefaultPlannerModel implementation
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public class PlannerModel
+    implements Serializable
+{
+    //~ Instance fields --------------------------------------------------------
+
+    private HashMap entities;
+    private TreeSet days;
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Creates a new PlannerModel object.
+     */
+    public PlannerModel()
+    {
+        days = new TreeSet();
+        entities = new HashMap();
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * <p>
+     * Set the day
+     * </p>
+     *
+     * @param date the new day
+     *
+     * @return true if successful
+     */
+    public boolean setDay(Date date)
+    {
+        if (date == null) {
+            return false;
+        }
+
+        days.clear();
+        add(date);
+
+        return true;
+    }
+
+    /**
+     * <p>
+     * Get the day at position <i>index</i>
+     * </p>
+     *
+     * @param index the index
+     *
+     * @return the day
+     */
+    public Day getDay(int index)
+    {
+        Object[] dayArray = days.toArray();
+
+        return (Day) dayArray[index];
+    }
+
+    /**
+     * <p>
+     * Get the entity at position <i>index</i>
+     * </p>
+     *
+     * @param id the index
+     *
+     * @return the entity
+     */
+    public PlannerEntity getEntity(String id)
+    {
+        return (PlannerEntity) entities.get(id);
+    }
+
+    /**
+     * <p>
+     * Assign a special status to a day, e.g. a holiday
+     * </p>
+     *
+     * @param date the date
+     * @param isWorkingDay whether the day is a normal working day
+     * @param specialDayName the name of the holiday
+     *
+     * @return true if successful
+     */
+    public boolean setSpecialDay(
+        Date date,
+        boolean isWorkingDay,
+        String specialDayName
+    )
+    {
+        if ((date == null) || !containsDate(date)) {
+            return false;
+        }
+
+        for (Iterator dayIterator = dayIterator(); dayIterator.hasNext();) {
+            Day day = (Day) dayIterator.next();
+            day.setWorkingDay(isWorkingDay);
+            day.setSpecialDayName(specialDayName);
+        }
+
+        return true;
+    }
+
+    /**
+     * <p>
+     * Add a day to the planner
+     * </p>
+     *
+     * @param date the date that should be added
+     * @param isWorkingDay whether the day is a normal working day
+     * @param specialDayName the name of the holiday, if any
+     *
+     * @return the day that was added
+     */
+    public Day add(
+        Date date,
+        boolean isWorkingDay,
+        String specialDayName
+    )
+    {
+        if (date == null) {
+            return null;
+        }
+
+        Day day = new Day(date);
+        day.setWorkingDay(isWorkingDay);
+        day.setSpecialDayName(specialDayName);
+        days.add(day);
+
+        return day;
+    }
+
+    /**
+     * <p>
+     * Add an entity to the planner
+     * </p>
+     *
+     * @param entity the entity to add
+     *
+     * @return true if successful
+     */
+    public boolean add(PlannerEntity entity)
+    {
+        if ((entity == null) || entities.containsKey(entity.getId())) {
+            return false;
+        }
+
+        entities.put(entity.getId(), entity);
+
+        return true;
+    }
+
+    /**
+     * <p>
+     * Add an entity to the planner
+     * </p>
+     *
+     * @param id the id of the entity
+     * @param name the name of the entity
+     *
+     * @return the entity that was added
+     */
+    public PlannerEntity add(
+        String id,
+        String name
+    )
+    {
+        PlannerEntity entity = new PlannerEntity(id, name);
+
+        if (add(entity)) {
+            return entity;
+        }
+
+        return null;
+    }
+
+    /**
+     * <p>
+     * Add a day to the planner
+     * </p>
+     *
+     * @param day the day to add
+     *
+     * @return the day that was added
+     */
+    public Day add(Day day)
+    {
+        if (day != null) {
+            days.add(day);
+        }
+
+        return day;
+    }
+
+    /**
+     * <p>
+     * Add a day to the planner
+     * </p>
+     *
+     * @param date the day to add
+     *
+     * @return the day that was added
+     */
+    public Day add(Date date)
+    {
+        return add(date, true, null);
+    }
+
+    /**
+     * <p>
+     * Add a schedule entry to the planner
+     * </p>
+     *
+     * @param entityId the id of the entity to which the entry applies
+     * @param entry the entry to add
+     *
+     * @return true if successful
+     */
+    public boolean addEntry(
+        String entityId,
+        ScheduleEntry entry
+    )
+    {
+        PlannerEntity entity = getEntity(entityId);
+
+        if (entity == null) {
+            return false;
+        }
+
+        return entity.addEntry(entry);
+    }
+
+    /**
+     * <p>
+     * Remove all days and all entities
+     * </p>
+     */
+    public void clear()
+    {
+        days.clear();
+        entities.clear();
+    }
+
+    /**
+     * <p>
+     * Check if the planner contains the specified date
+     * </p>
+     *
+     * @param date the date to check
+     *
+     * @return true if successful
+     */
+    public boolean containsDate(Date date)
+    {
+        for (Iterator iterator = days.iterator(); iterator.hasNext();) {
+            Day day = (Day) iterator.next();
+
+            if (day.equalsDate(date)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @return an iterator for the days of the planner
+     */
+    public Iterator dayIterator()
+    {
+        return days.iterator();
+    }
+
+    /**
+     * @return an iterator for the entities of the planner
+     */
+    public Iterator entityIterator()
+    {
+        return entities.values().iterator();
+    }
+
+    /**
+     * @return the number of days that are shown in the planner
+     */
+    public int numberOfDays()
+    {
+        return days.size();
+    }
+
+    /**
+     * @return the number of entities that are shown in the planner
+     */
+    public int numberOfEntities()
+    {
+        return entities.size();
+    }
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleDay.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleDay.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleDay.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleDay.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+
+import java.io.Serializable;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import org.apache.myfaces.custom.schedule.util.ScheduleEntryComparator;
+
+
+/**
+ * <p>
+ * This class represents one day in the schedule component
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public class ScheduleDay
+    extends Day
+    implements Serializable, Comparable
+{
+    //~ Instance fields --------------------------------------------------------
+
+    private final TreeSet entries;
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Creates a new ScheduleDay object.
+     *
+     * @param date the date
+     */
+    public ScheduleDay(Date date)
+    {
+        super(date);
+        this.entries = new TreeSet(new ScheduleEntryComparator());
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @return true if there are no schedule entries
+     */
+    public boolean isEmpty()
+    {
+        return entries.isEmpty();
+    }
+
+    /**
+     * <p>
+     * Add an entry to this day
+     * </p>
+     *
+     * @param entry the entry to add
+     *
+     * @return true if successful
+     */
+    public boolean addEntry(ScheduleEntry entry)
+    {
+        if (
+            (entry == null) || (entry.getStartTime() == null) ||
+                (entry.getEndTime() == null)
+        ) {
+            return false;
+        }
+
+        Calendar cal = GregorianCalendar.getInstance();
+        cal.setTime(entry.getEndTime());
+        cal.add(Calendar.DATE, 1);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+
+        Date endDate = cal.getTime();
+        cal.setTime(entry.getStartTime());
+
+        while (cal.getTime().before(endDate)) {
+            if (equalsDate(cal.getTime())) {
+                entries.add(entry);
+
+                return true;
+            }
+
+            cal.add(Calendar.DATE, 1);
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * Remove all entries from this day
+     * </p>
+     */
+    public void clear()
+    {
+        entries.clear();
+    }
+
+    /**
+     * @return an iterator for the schedule entries of this day
+     */
+    public Iterator iterator()
+    {
+        return entries.iterator();
+    }
+
+    /**
+     * <p>
+     * Remove an entry from this day
+     * </p>
+     *
+     * @param entry the entry to remove
+     *
+     * @return true if successful
+     */
+    public boolean remove(ScheduleEntry entry)
+    {
+        return entries.remove(entry);
+    }
+
+    /**
+     * @return the number of entries that are shown on this day
+     */
+    public int size()
+    {
+        return entries.size();
+    }
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleEntry.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleEntry.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleEntry.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleEntry.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+import java.util.Date;
+
+
+/**
+ * <p>
+ * A schedule entry is an appointment or event.
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public interface ScheduleEntry
+{
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @return Returns the description.
+     */
+    public abstract String getDescription();
+
+    /**
+     * @return Returns the endTime.
+     */
+    public abstract Date getEndTime();
+
+    /**
+     * @return Returns the id.
+     */
+    public abstract String getId();
+
+    /**
+     * @return Returns the startTime.
+     */
+    public abstract Date getStartTime();
+
+    /**
+     * @return Returns the subtitle.
+     */
+    public abstract String getSubtitle();
+
+    /**
+     * @return Returns the title.
+     */
+    public abstract String getTitle();
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleModel.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleModel.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleModel.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/ScheduleModel.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+import java.util.Date;
+import java.util.Iterator;
+
+
+/**
+ * <p>
+ * The underlying model of the UISchedule component. You should implement this
+ * interface when creating real implementations, which would typically be backed
+ * by a database.
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public interface ScheduleModel
+{
+    //~ Static fields/initializers ---------------------------------------------
+
+    public static final int DAY = 0;
+    public static final int WORKWEEK = 1;
+    public static final int WEEK = 2;
+    public static final int MONTH = 3;
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @return true if there are no entries
+     */
+    public abstract boolean isEmpty();
+
+    /**
+     * @param mode the mode: DAY, WORKWEEK, WEEK or MONTH
+     */
+    public abstract void setMode(int mode);
+
+    /**
+     * @return the mode: DAY, WORKWEEK, WEEK or MONTH
+     */
+    public abstract int getMode();
+
+    /**
+     * @param date the date to select
+     */
+    public abstract void setSelectedDate(Date date);
+
+    /**
+     * @return the selected date
+     */
+    public abstract Date getSelectedDate();
+
+    /**
+     * @param selectedEntry the entry to select
+     */
+    public abstract void setSelectedEntry(ScheduleEntry selectedEntry);
+
+    /**
+     * @return the selected entry
+     */
+    public abstract ScheduleEntry getSelectedEntry();
+
+    /**
+     * <p>
+     * Check if the schedule contains the specified date
+     * </p>
+     *
+     * @param date the date to check
+     *
+     * @return whether the schedule containts this date
+     */
+    public abstract boolean containsDate(Date date);
+
+    /**
+     * <p>
+     * Get the day at position <i>index</i>.
+     * </p>
+     *
+     * @param index the index
+     *
+     * @return the day
+     */
+    public abstract Object get(int index);
+
+    /**
+     * @return an iterator for the days
+     */
+    public abstract Iterator iterator();
+
+    /**
+     * @return the number of days in this model
+     */
+    public abstract int size();
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/SimpleScheduleModel.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/SimpleScheduleModel.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/SimpleScheduleModel.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/model/SimpleScheduleModel.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.model;
+
+
+import java.io.Serializable;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import org.apache.myfaces.custom.schedule.util.ScheduleEntryComparator;
+
+
+/**
+ * <p>
+ * A simple implementation of the ScheduleModel, not backed by any kind of
+ * datasource: entries have to be added manually.
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public class SimpleScheduleModel
+    extends AbstractScheduleModel
+    implements Serializable
+{
+    //~ Instance fields --------------------------------------------------------
+
+    private final TreeSet entries;
+    private final HashMap holidays;
+    private final DateFormat holidayFormat = new SimpleDateFormat("yyyyMMdd");
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Creates a new SimpleScheduleModel object.
+     */
+    public SimpleScheduleModel()
+    {
+        this.entries = new TreeSet(new ScheduleEntryComparator());
+        this.holidays = new HashMap();
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * <p>
+     * Set the name of a holiday
+     * </p>
+     *
+     * @param date the date
+     * @param holidayName the name of the holiday
+     *
+     * @return true if successful
+     */
+    public void setHoliday(
+        Date date,
+        String holidayName
+    )
+    {
+        if (date == null) {
+            return;
+        }
+        
+        String key = holidayFormat.format(date);
+        holidays.put(key, holidayName);
+    }
+
+    /**
+     * <p>
+     * Add an entry to the model
+     * </p>
+     *
+     * @param entry the entry to add
+     *
+     * @return true if successful
+     */
+    public void addEntry(ScheduleEntry entry)
+    {
+        entries.add(entry);
+    }
+
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.AbstractScheduleModel#loadEntries(java.util.Date, java.util.Date)
+     */
+    protected Collection loadEntries(
+        Date startDate,
+        Date endDate
+    )
+    {
+        ArrayList selection = new ArrayList();
+
+        for (Iterator entryIterator = entries.iterator();
+                entryIterator.hasNext();
+        ) {
+            ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
+
+            if (
+                entry.getEndTime().before(startDate) ||
+                    entry.getStartTime().after(endDate)
+            ) {
+                continue;
+            }
+
+            selection.add(entry);
+        }
+
+        return selection;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.AbstractScheduleModel#loadDayAttributes(org.apache.myfaces.custom.schedule.model.Day)
+     */
+    protected void loadDayAttributes(Day day) {
+        if (day == null) return;
+        String key = holidayFormat.format(day.getDate());
+        String holiday = (String)holidays.get(key);
+        if (holiday == null) return;
+        day.setSpecialDayName(holiday);
+        day.setWorkingDay(false);
+    }
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/renderer/AbstractCompactScheduleRenderer.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/renderer/AbstractCompactScheduleRenderer.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/renderer/AbstractCompactScheduleRenderer.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/renderer/AbstractCompactScheduleRenderer.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.renderer;
+
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeSet;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.myfaces.custom.schedule.HtmlSchedule;
+import org.apache.myfaces.custom.schedule.model.Day;
+import org.apache.myfaces.custom.schedule.model.ScheduleDay;
+import org.apache.myfaces.custom.schedule.model.ScheduleEntry;
+import org.apache.myfaces.renderkit.html.HTML;
+
+
+/**
+ * <p>
+ * Abstract superclass for the week and month view renderers.
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @author Bruno Aranda (adaptation of Jurgen's code to myfaces)
+ * @version $Revision$
+ */
+public abstract class AbstractCompactScheduleRenderer
+    extends AbstractScheduleRenderer
+{
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see javax.faces.render.Renderer#encodeChildren(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeChildren(
+        FacesContext context,
+        UIComponent component
+    )
+        throws IOException
+    {
+        //the children are rendered in the encodeBegin phase
+    }
+
+    /**
+     * @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeEnd(
+        FacesContext context,
+        UIComponent component
+    )
+        throws IOException
+    {
+        //all rendering is done in the begin phase
+    }
+
+    /**
+     * @return The default height, in pixels, of one row in the schedule grid
+     */
+    protected abstract int getDefaultRowHeight();
+
+    /**
+     * @return The name of the property that determines the row height
+     */
+    protected abstract String getRowHeightProperty();
+
+    /**
+     * @param attributes The attributes
+     *
+     * @return The row height, in pixels
+     */
+    protected int getRowHeight(Map attributes)
+    {
+        int rowHeight = 0;
+
+        try {
+            rowHeight =
+                Integer.valueOf(
+                    (String) attributes.get(getRowHeightProperty())
+                ).intValue();
+        } catch (Exception e) {
+            rowHeight = 0;
+        }
+
+        if (rowHeight <= 0) {
+            rowHeight = getDefaultRowHeight();
+        }
+
+        return rowHeight;
+    }
+
+    /**
+     * <p>
+     * Draw one day in the schedule
+     * </p>
+     *
+     * @param context the FacesContext
+     * @param writer the ResponseWriter
+     * @param schedule the schedule
+     * @param day the day that should be drawn
+     * @param cellWidth the width of the cell
+     * @param dayOfWeek the day of the week
+     * @param dayOfMonth the day of the month
+     * @param isWeekend is it a weekend day?
+     * @param isCurrentMonth is the day in the currently selected month?
+     * @param rowspan the rowspan for the table cell
+     *
+     * @throws IOException when the cell could not be drawn
+     */
+    protected void writeDayCell(
+        FacesContext context,
+        ResponseWriter writer,
+        HtmlSchedule schedule,
+        ScheduleDay day,
+        float cellWidth,
+        int dayOfWeek,
+        int dayOfMonth,
+        boolean isWeekend,
+        boolean isCurrentMonth,
+        int rowspan
+    )
+        throws IOException
+    {
+        Map attributes = schedule.getAttributes();
+        writer.startElement(HTML.TD_ELEM, schedule);
+
+        writer.writeAttribute("rowspan", String.valueOf(rowspan), null);
+
+        writer.writeAttribute(
+            HTML.CLASS_ATTR, isCurrentMonth ? "day" : "inactive-day", null
+        );
+
+        //determine the height of the day in pixels
+        StringBuffer styleBuffer = new StringBuffer();
+        styleBuffer.append("height: ");
+
+        int myRowHeight = 0;
+        int myContentHeight = 0;
+
+        if (isWeekend) {
+            myRowHeight = getRowHeight(attributes) / 2;
+            myContentHeight = myRowHeight - 19;
+        } else {
+            myRowHeight = getRowHeight(attributes) + 1; //need to add 1 to get the weekends right
+            myContentHeight = myRowHeight - 18; //18 instead of 19, to get the weekends right
+        }
+
+        styleBuffer.append(myRowHeight);
+        styleBuffer.append("px;");
+
+        writer.writeAttribute(
+            HTML.STYLE_ATTR, styleBuffer.toString() + " width: " + cellWidth + "%;",
+            null
+        );
+
+        writer.startElement(HTML.TABLE_ELEM, schedule);
+
+        writer.writeAttribute(HTML.CLASS_ATTR, "day", null);
+        writer.writeAttribute(
+            HTML.STYLE_ATTR, styleBuffer.toString() + " width: 100%;", null
+        );
+
+        writer.writeAttribute(HTML.CELLPADDING_ATTR, "0", null);
+        writer.writeAttribute(HTML.CELLSPACING_ATTR, "0", null);
+
+        //day header
+        writer.startElement(HTML.TR_ELEM, schedule);
+        writer.startElement(HTML.TD_ELEM, schedule);
+        writer.writeAttribute(HTML.CLASS_ATTR, "header", null);
+        writer.writeAttribute(
+            HTML.STYLE_ATTR, "height: 18px; width: 100%; overflow: hidden", null
+        );
+        writer.writeText(
+            getDateString(context, schedule.getAttributes(), day.getDate()),
+            null
+        );
+        writer.endElement(HTML.TD_ELEM);
+        writer.endElement(HTML.TR_ELEM);
+
+        //day content
+        writer.startElement(HTML.TR_ELEM, schedule);
+        writer.startElement(HTML.TD_ELEM, schedule);
+
+        writer.writeAttribute(HTML.CLASS_ATTR, "content", null);
+
+        //determine the height of the day content in pixels
+        StringBuffer contentStyleBuffer = new StringBuffer();
+        contentStyleBuffer.append("height: ");
+        contentStyleBuffer.append(myContentHeight);
+        contentStyleBuffer.append("px; width: 100%;");
+        writer.writeAttribute(HTML.STYLE_ATTR, contentStyleBuffer.toString(), null);
+
+        writer.startElement(HTML.DIV_ELEM, schedule);
+        writer.writeAttribute(
+            HTML.STYLE_ATTR,
+            "width: 100%; height: 100%; overflow: auto; vertical-align: top;",
+            null
+        );
+        writer.startElement(HTML.TABLE_ELEM, schedule);
+        writer.writeAttribute(HTML.STYLE_ATTR, "width: 100%;", null);
+
+        writeEntries(context, schedule, day, writer);
+
+        writer.endElement(HTML.TABLE_ELEM);
+        writer.endElement(HTML.DIV_ELEM);
+        writer.endElement(HTML.TD_ELEM);
+        writer.endElement(HTML.TR_ELEM);
+        writer.endElement(HTML.TABLE_ELEM);
+        writer.endElement(HTML.TD_ELEM);
+    }
+
+    /**
+     * <p>
+     * Draw the schedule entries in the specified day cell
+     * </p>
+     *
+     * @param context the FacesContext
+     * @param schedule the schedule
+     * @param day the day
+     * @param writer the ResponseWriter
+     *
+     * @throws IOException when the entries could not be drawn
+     */
+    protected void writeEntries(
+        FacesContext context,
+        HtmlSchedule schedule,
+        ScheduleDay day,
+        ResponseWriter writer
+    )
+        throws IOException
+    {
+        UIForm parentForm = getParentForm(schedule);
+        TreeSet entrySet = new TreeSet(comparator);
+
+        for (Iterator entryIterator = day.iterator(); entryIterator.hasNext();) {
+            ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
+            entrySet.add(entry);
+        }
+
+        for (
+            Iterator entryIterator = entrySet.iterator();
+                entryIterator.hasNext();
+        ) {
+            ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
+            writer.startElement(HTML.TR_ELEM, schedule);
+            writer.startElement(HTML.TD_ELEM, schedule);
+
+            if (isSelected(schedule, entry)) {
+                writer.writeAttribute(HTML.CLASS_ATTR, "selected", null);
+            }
+
+            writer.writeAttribute(HTML.STYLE_ATTR, "width: 100%", null);
+
+            //draw the tooltip
+            if (showTooltip(schedule.getAttributes())) {
+                writer.writeAttribute(
+                    "onmouseover",
+                    getTooltipText(entry, schedule.getAttributes()), null
+                );
+            }
+
+            if (!isSelected(schedule, entry) && !schedule.isReadonly()) {
+                writer.startElement("a", schedule);
+                writer.writeAttribute("href", "#", null);
+
+                String clientId = schedule.getClientId(context);
+                StringBuffer mousedown = new StringBuffer();
+                mousedown.append("document.forms['");
+                mousedown.append(parentForm.getClientId(context));
+                mousedown.append("']['");
+                mousedown.append(clientId);
+                mousedown.append("'].value='");
+                mousedown.append(entry.getId());
+                mousedown.append("'; document.forms['");
+                mousedown.append(parentForm.getClientId(context));
+                mousedown.append("'].submit()");
+                writer.writeAttribute(
+                    "onmousedown", mousedown.toString(), null
+                );
+            }
+
+            writer.writeText(getEntryText(day, entry), null);
+
+            if (!isSelected(schedule, entry) && !schedule.isReadonly()) {
+                writer.endElement("a");
+            }
+
+            writer.endElement(HTML.TD_ELEM);
+            writer.endElement(HTML.TR_ELEM);
+        }
+    }
+
+    private String getEntryText(
+        Day day,
+        ScheduleEntry entry
+    )
+    {
+        StringBuffer text = new StringBuffer();
+        Date startTime = entry.getStartTime();
+
+        if (day.getDayStart().after(entry.getStartTime())) {
+            startTime = day.getDayStart();
+        }
+
+        Date endTime = entry.getEndTime();
+
+        if (day.getDayEnd().before(entry.getEndTime())) {
+            endTime = day.getDayEnd();
+        }
+
+        DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT);
+        text.append(format.format(startTime));
+        text.append("-");
+        text.append(format.format(endTime));
+        text.append(": ");
+        text.append(entry.getTitle());
+
+        String returnString = text.toString();
+
+        return returnString;
+    }
+
+    private boolean isSelected(
+        HtmlSchedule schedule,
+        ScheduleEntry entry
+    )
+    {
+        ScheduleEntry selectedEntry = schedule.getModel().getSelectedEntry();
+
+        if (selectedEntry == null) {
+            return false;
+        }
+
+        return selectedEntry.getId().equals(entry.getId());
+    }
+}
+//The End

Added: myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/renderer/AbstractScheduleRenderer.java
URL: http://svn.apache.org/viewcvs/myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/renderer/AbstractScheduleRenderer.java?rev=216175&view=auto
==============================================================================
--- myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/renderer/AbstractScheduleRenderer.java (added)
+++ myfaces/sandbox/trunk/src/java/org/apache/myfaces/custom/schedule/renderer/AbstractScheduleRenderer.java Wed Jul 13 08:33:22 2005
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.custom.schedule.renderer;
+
+
+import java.io.IOException;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import java.util.Date;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.event.ActionEvent;
+import javax.faces.render.Renderer;
+
+import org.apache.myfaces.custom.schedule.HtmlSchedule;
+import org.apache.myfaces.custom.schedule.model.ScheduleEntry;
+import org.apache.myfaces.custom.schedule.util.ScheduleEntryComparator;
+import org.apache.myfaces.custom.schedule.util.ScheduleUtil;
+import org.apache.myfaces.renderkit.html.HTML;
+
+
+/**
+ * <p>
+ * Abstract superclass for all renderer of the UISchedule component
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @author Bruno Aranda (adaptation of Jurgen's code to myfaces)
+ * @version $Revision$
+ */
+public class AbstractScheduleRenderer
+    extends Renderer
+{
+    //~ Static fields/initializers ---------------------------------------------
+
+    protected static final ScheduleEntryComparator comparator =
+        new ScheduleEntryComparator();
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void decode(
+        FacesContext context,
+        UIComponent component
+    )
+    {
+        if (ScheduleUtil.canModifyValue(component)) {
+            HtmlSchedule schedule = (HtmlSchedule) component;
+            Map parameters =
+                context.getExternalContext().getRequestParameterMap();
+            String selectedEntryId =
+                (String) parameters.get((String) schedule.getClientId(context));
+
+            if ((selectedEntryId != null) && (selectedEntryId.length() > 0)) {
+                schedule.setSubmittedEntry(schedule.findEntry(selectedEntryId));
+                schedule.queueEvent(new ActionEvent(schedule));
+            }
+        }
+    }
+
+    /**
+     * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeBegin(
+        FacesContext context,
+        UIComponent component
+    )
+        throws IOException
+    {
+        if (!component.isRendered()) {
+            return;
+        }
+
+        HtmlSchedule schedule = (HtmlSchedule) component;
+        Map attributes = schedule.getAttributes();
+        ResponseWriter writer = context.getResponseWriter();
+
+        //hidden input field containing the id of the selected entry
+        writer.startElement(HTML.INPUT_ELEM, schedule);
+        writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
+        writer.writeAttribute(
+            HTML.NAME_ATTR, schedule.getClientId(context), "clientId"
+        );
+        writer.endElement(HTML.INPUT_ELEM);
+    }
+
+    /**
+     * <p>
+     * Get the String representation of a date, taking into account the
+     * specified date format or the current Locale.
+     * </p>
+     *
+     * @param context the FacesContext
+     * @param attributes the attributes
+     * @param date the date
+     *
+     * @return the date string
+     */
+    protected String getDateString(
+        FacesContext context,
+        Map attributes,
+        Date date
+    )
+    {
+        DateFormat format;
+        String pattern = getHeaderDateFormat(attributes);
+
+        if ((pattern != null) && (pattern.length() > 0)) {
+            format = new SimpleDateFormat(pattern);
+        } else {
+            if (context.getApplication().getDefaultLocale() != null) {
+                format =
+                    DateFormat.getDateInstance(
+                        DateFormat.MEDIUM,
+                        context.getApplication().getDefaultLocale()
+                    );
+            } else {
+                format = DateFormat.getDateInstance(DateFormat.MEDIUM);
+            }
+        }
+
+        return format.format(date);
+    }
+
+    /**
+     * <p>
+     * The date format that is used in the schedule header
+     * </p>
+     *
+     * @param attributes the attributes
+     *
+     * @return Returns the headerDateFormat.
+     */
+    protected String getHeaderDateFormat(Map attributes)
+    {
+        return (String) attributes.get("headerDateFormat");
+    }
+
+    /**
+     * <p>
+     * Get the parent form of the schedule component
+     * </p>
+     *
+     * @param component the component
+     *
+     * @return the parent form
+     */
+    protected UIForm getParentForm(UIComponent component)
+    {
+        UIComponent parent = component.getParent();
+
+        while (parent != null) {
+            if (parent instanceof UIForm) {
+                break;
+            }
+
+            parent = parent.getParent();
+        }
+
+        return (UIForm) parent;
+    }
+
+    /**
+     * <p>
+     * Assemble the tooltip text for the specified entry
+     * </p>
+     *
+     * @param entry the entry
+     * @param attributes the attributes
+     *
+     * @return the tooltip text
+     */
+    protected String getTooltipText(
+        ScheduleEntry entry,
+        Map attributes
+    )
+    {
+        if (!showTooltip(attributes)) {
+            return null;
+        }
+
+        //TODO enable tooltips again
+        
+        return "";
+        
+        /*
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(
+            "return makeTrue(domTT_activate(this, event, 'caption', '"
+        );
+
+        if (entry.getTitle() != null) {
+            buffer.append(escape(entry.getTitle()));
+        }
+
+        buffer.append("', 'content', '<i>");
+
+        if (entry.getSubtitle() != null) {
+            buffer.append(escape(entry.getSubtitle()));
+        }
+
+        buffer.append("</i>");
+
+        if (entry.getDescription() != null) {
+            buffer.append("<br/>");
+            buffer.append(escape(entry.getDescription()));
+        }
+
+        buffer.append("', 'trail', true));");
+
+        return buffer.toString();
+        */
+    }
+
+    /**
+     * <p>
+     * Should the tooltip be made visible?
+     * </p>
+     *
+     * @param attributes the attributes
+     *
+     * @return whether or not tooltips should be rendered
+     */
+    protected boolean showTooltip(Map attributes)
+    {
+        return Boolean.valueOf((String) attributes.get("tooltip")).booleanValue();
+    }
+
+    private String escape(String text)
+    {
+        if (text == null) {
+            return null;
+        }
+
+        return text.replaceAll("'", "&quot;");
+    }
+}
+//The End