/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
// www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////
package org.projectforge.plugins.teamcal.integration;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.projectforge.plugins.teamcal.admin.TeamCalCache;
import org.projectforge.plugins.teamcal.admin.TeamCalDO;
import org.projectforge.plugins.teamcal.dialog.TeamCalFilterDialog;
import org.projectforge.user.PFUserContext;
import org.projectforge.web.timesheet.TimesheetEventsProvider;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
/**
* Persist the settings of one named filter entry.
* @author M. Lauterbach (m.lauterbach@micromata.de)
* @author K. Reinhard (k.reinhard@micromata.de)
*
*/
public class TemplateEntry implements Serializable, Comparable<TemplateEntry>, Cloneable
{
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(TemplateEntry.class);
private static final long serialVersionUID = 409057949195992116L;
private final Set<TemplateCalendarProperties> calendarProperties = new TreeSet<TemplateCalendarProperties>();
private Set<Integer> visibleCalendarIds;
@XStreamAsAttribute
private String name;
@XStreamAsAttribute
private Integer defaultCalendarId;
@XStreamAsAttribute
private Boolean showBirthdays;
@XStreamAsAttribute
private Boolean showStatistics;
@XStreamAsAttribute
private Integer timesheetUserId;
@XStreamAsAttribute
private String selectedCalendar;
@XStreamAsAttribute
private Boolean showBreaks = true;
@XStreamAsAttribute
private Boolean showPlanning;
public Set<TemplateCalendarProperties> getCalendarProperties()
{
return calendarProperties;
}
/**
* @return the name
*/
public String getName()
{
return name;
}
/**
* @param name the name to set
* @return this for chaining.
*/
public TemplateEntry setName(final String name)
{
this.name = name;
return this;
}
public TemplateCalendarProperties addNewCalendarProperties(final TeamCalCalendarFilter filter, final Integer calId)
{
Validate.notNull(calId);
final TemplateCalendarProperties props = new TemplateCalendarProperties();
props.setCalId(calId);
props.setColorCode(filter.getUsedColor(calId));
this.calendarProperties.add(props);
this.visibleCalendarIds = null;
return props;
}
public void removeCalendarProperties(final Integer calId)
{
Validate.notNull(calId);
final TemplateCalendarProperties props = getCalendarProperties(calId);
if (props != null) {
this.calendarProperties.remove(props);
}
this.visibleCalendarIds = null;
}
public String getColorCode(final Integer calendarId)
{
final TemplateCalendarProperties props = getCalendarProperties(calendarId);
if (props == null) {
return null;
}
return props.getColorCode();
}
public TemplateCalendarProperties getCalendarProperties(final Integer calendarId)
{
if (calendarId == null) {
return null;
}
for (final TemplateCalendarProperties props : calendarProperties) {
if (calendarId.equals(props.getCalId()) == true) {
return props;
}
}
return null;
}
public boolean contains(final Integer calendarId)
{
return getCalendarProperties(calendarId) != null;
}
public boolean isVisible(final Integer calendarId)
{
final TemplateCalendarProperties props = getCalendarProperties(calendarId);
return props != null && props.isVisible();
}
/**
* @return the visibleCalendarIds
*/
public Set<Integer> getVisibleCalendarIds()
{
if (this.visibleCalendarIds == null) {
this.visibleCalendarIds = new HashSet<Integer>();
for (final TemplateCalendarProperties props : this.calendarProperties) {
if (props.isVisible() == true) {
this.visibleCalendarIds.add(props.getCalId());
}
}
}
return this.visibleCalendarIds;
}
/**
* @return All contained calendars (visible and not visible ones).
*/
public List<TeamCalDO> getCalendars()
{
final List<TeamCalDO> result = new ArrayList<TeamCalDO>();
final TeamCalCache cache = TeamCalCache.getInstance();
for (final TemplateCalendarProperties props : this.calendarProperties) {
final TeamCalDO cal = cache.getCalendar(props.getCalId());
if (cal != null) {
result.add(cal);
} else {
log.error("Oups, calendar with id " + props.getCalId() + " not found in TeamCalCache.");
}
}
return result;
}
/**
* @return All contained calendars (visible and not visible ones).
*/
public Set<Integer> getCalendarIds()
{
final Set<Integer> result = new HashSet<Integer>();
for (final TemplateCalendarProperties props : this.calendarProperties) {
result.add(props.getCalId());
}
return result;
}
/**
* Should be called every time if new entries are added or the visibility of any entry was changed. After recalculation of visible
* calendars is forced.
*/
public void setDirty()
{
this.visibleCalendarIds = null;
}
/**
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(final TemplateEntry o)
{
if (this == o) {
return 0;
}
if (this.name == null) {
if (o.name == null) {
return 0;
}
return -1;
}
if (o.name == null) {
return 1;
}
return this.name.compareTo(o.name);
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(final Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final TemplateEntry other = (TemplateEntry) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public TemplateEntry clone()
{
// try {
final TemplateEntry cloned = new TemplateEntry(); // super.clone();
cloned.name = this.name;
cloned.defaultCalendarId = this.defaultCalendarId;
cloned.showBirthdays = this.showBirthdays;
cloned.showBreaks = this.showBreaks;
cloned.showPlanning = this.showPlanning;
cloned.showStatistics = this.showStatistics;
cloned.timesheetUserId = this.timesheetUserId;
for (final TemplateCalendarProperties props : this.calendarProperties) {
final TemplateCalendarProperties clonedProps = props.clone();
cloned.calendarProperties.add(clonedProps);
}
cloned.setDirty();
return cloned;
// } catch (final CloneNotSupportedException ex) {
// log.error(ex.getMessage(), ex);
// return null;
// }
}
/**
* For avoiding reload of Calendar if no changes are detected. (Was für'n Aufwand für so'n kleines Feature...)
* @param filter
* @return
*/
public boolean isModified(final TemplateEntry other)
{
if (StringUtils.equals(this.name, other.name) == false) {
return true;
}
if (calendarProperties.size() != other.calendarProperties.size()) {
return true;
}
if (ObjectUtils.equals(defaultCalendarId, other.defaultCalendarId) == false //
|| ObjectUtils.equals(showBirthdays, other.showBirthdays) == false //
|| ObjectUtils.equals(showBreaks, other.showBreaks) == false
|| ObjectUtils.equals(showPlanning, other.showPlanning) == false
|| ObjectUtils.equals(showStatistics, other.showStatistics) == false
|| ObjectUtils.equals(timesheetUserId, other.timesheetUserId) == false) {
return true;
}
final Iterator<TemplateCalendarProperties> it1 = this.calendarProperties.iterator();
final Iterator<TemplateCalendarProperties> it2 = other.calendarProperties.iterator();
while (it1.hasNext() == true) {
final TemplateCalendarProperties entry1 = it1.next();
final TemplateCalendarProperties entry2 = it2.next();
if (entry1.isModified(entry2) == true) {
return true;
}
}
return false;
}
/**
* @return the defaultCalendarId
*/
public Integer getDefaultCalendarId()
{
return defaultCalendarId;
}
/**
* @param defaultCalendarId the defaultCalendarId to set
* @return this for chaining.
*/
public TemplateEntry setDefaultCalendarId(final Integer defaultCalendarId)
{
this.defaultCalendarId = defaultCalendarId;
return this;
}
/**
* @return the showBirthdays
*/
public boolean isShowBirthdays()
{
return showBirthdays == Boolean.TRUE;
}
/**
* @param showBirthdays the showBirthdays to set
* @return this for chaining.
*/
public TemplateEntry setShowBirthdays(final boolean showBirthdays)
{
this.showBirthdays = showBirthdays;
return this;
}
/**
* @return the showBreaks
*/
public boolean isShowBreaks()
{
return showBreaks == Boolean.TRUE;
}
/**
* @param showBreaks the showBreaks to set
* @return this for chaining.
*/
public TemplateEntry setShowBreaks(final boolean showBreaks)
{
this.showBreaks = showBreaks;
return this;
}
/**
* @return the showPlanning
*/
public boolean isShowPlanning()
{
return showPlanning == Boolean.TRUE;
}
/**
* @param showPlanning the showPlanning to set
* @return this for chaining.
*/
public TemplateEntry setShowPlanning(final boolean showPlanning)
{
this.showPlanning = showPlanning;
return this;
}
/**
* @return the showStatistics
*/
public boolean isShowStatistics()
{
return showStatistics == Boolean.TRUE;
}
/**
* @param showStatistics the showStatistics to set
* @return this for chaining.
*/
public TemplateEntry setShowStatistics(final boolean showStatistics)
{
this.showStatistics = showStatistics;
return this;
}
/**
* @return the timesheetUserId
*/
public Integer getTimesheetUserId()
{
return timesheetUserId;
}
/**
* Used for users with access to display own and other time-sheets.
* @param timesheetUserId the timesheetUserId to set
* @return this for chaining.
*/
public TemplateEntry setTimesheetUserId(final Integer timesheetUserId)
{
this.timesheetUserId = timesheetUserId;
return this;
}
/**
* @see org.projectforge.web.calendar.ICalendarFilter#isShowTimesheets()
*/
public boolean isShowTimesheets()
{
return this.timesheetUserId != null;
}
/**
* @see org.projectforge.web.calendar.ICalendarFilter#setShowTimesheets(boolean)
*/
public TemplateEntry setShowTimesheets(final boolean showTimesheets)
{
this.timesheetUserId = PFUserContext.getUserId();
return this;
}
/**
* @see org.projectforge.web.calendar.ICalendarFilter#getSelectedCalendar()
*/
public String getSelectedCalendar()
{
return selectedCalendar;
}
/**
* @see org.projectforge.web.calendar.ICalendarFilter#setSelectedCalendar(java.lang.String)
*/
public TemplateEntry setSelectedCalendar(final String selectedCalendar)
{
this.selectedCalendar = selectedCalendar;
return this;
}
public static String calcCalendarStringForCalendar(final Integer calendarId)
{
if (TeamCalFilterDialog.TIMESHEET_CALENDAR_ID.equals(calendarId) || calendarId == null) {
return TimesheetEventsProvider.EVENT_CLASS_NAME;
} else {
return String.valueOf(calendarId);
}
}
}