001/*
002 *  Copyright 2014 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.workspaces.calendars.jcr;
017
018import java.time.ZonedDateTime;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import javax.jcr.Node;
024
025import org.apache.commons.lang3.StringUtils;
026
027import org.ametys.cms.repository.DefaultIndexableTraversableAmetysObject;
028import org.ametys.plugins.explorer.ExplorerNode;
029import org.ametys.plugins.explorer.ModifiableExplorerNode;
030import org.ametys.plugins.repository.AmetysObject;
031import org.ametys.plugins.repository.AmetysObjectIterable;
032import org.ametys.plugins.repository.AmetysRepositoryException;
033import org.ametys.plugins.workspaces.calendars.Calendar;
034import org.ametys.plugins.workspaces.calendars.WorkflowAwareCalendar;
035import org.ametys.plugins.workspaces.calendars.events.CalendarEvent;
036import org.ametys.plugins.workspaces.calendars.events.CalendarEventOccurrence;
037import org.ametys.plugins.workspaces.project.objects.Project;
038
039/**
040 * Default implementation of an {@link Calendar}, backed by a JCR node.<br>
041 */
042public class JCRCalendar extends DefaultIndexableTraversableAmetysObject<JCRCalendarFactory> implements WorkflowAwareCalendar, ModifiableExplorerNode
043{
044    /** application id for resources collections. */
045    public static final String APPLICATION_ID = "Ametys.plugins.explorer.applications.Calendar";
046    
047    /** Constants for title Calendar* */
048    public static final String CALENDAR_TITLE = "title";
049    
050    /** Constants for description Calendar* */
051    public static final String CALENDAR_DESC = "description";
052    
053    /** Constants for color Calendar* */
054    public static final String CALENDAR_COLOR = "color";
055    
056    /** Constants for color Visibility* */
057    public static final String CALENDAR_VISIBILITY = "visibility";
058    
059    /** Constants for workflowName Calendar* */
060    public static final String CALENDAR_WORKFLOW_NAME = "workflowName";
061    
062    /** Constants for template description Calendar* */
063    public static final String CALENDAR_TEMPLATE_DESC = "template-description";
064    
065    /** Constants for Calendar ICS token */
066    public static final String CALENDAR_ICS_TOKEN = "ics-token";
067    
068    /**
069     * Creates an {@link JCRCalendar}.
070     * @param node the node backing this {@link AmetysObject}
071     * @param parentPath the parentPath in the Ametys hierarchy
072     * @param factory the DefaultAmetysObjectFactory which created the AmetysObject
073     */
074    public JCRCalendar(Node node, String parentPath, JCRCalendarFactory factory)
075    {
076        super(node, parentPath, factory);
077    }
078
079    public String getIconCls()
080    {
081        return "calendar";
082    }
083
084    public String getApplicationId()
085    {
086        return APPLICATION_ID;
087    }
088
089    public Project getProject()
090    {
091        return _getFactory().getProjectManager().getParentProject(this);
092    }
093    
094    public String getExplorerPath()
095    {
096        AmetysObject parent = getParent();
097        
098        if (parent instanceof ExplorerNode)
099        {
100            return ((ExplorerNode) parent).getExplorerPath() + "/" + getName();
101        }
102        else
103        {
104            return "";
105        }
106    }
107    
108    public String getDescription()
109    {
110        return getValue(CALENDAR_DESC);
111    }
112
113    public String getColor()
114    {
115        return getValue(CALENDAR_COLOR);
116    }
117    
118    public CalendarVisibility getVisibility()
119    {
120        if (hasValue(CALENDAR_VISIBILITY))
121        {
122            return CalendarVisibility.valueOf(getValue(CALENDAR_VISIBILITY));
123        }
124        else
125        {
126            return CalendarVisibility.PRIVATE;
127        }
128    }
129    
130    public String getWorkflowName()
131    {
132        return getValue(CALENDAR_WORKFLOW_NAME);
133    }
134    
135    public String getTemplateDescription()
136    {
137        return getValueOrDefault(CALENDAR_TEMPLATE_DESC, StringUtils.EMPTY);
138    }
139    
140    public List<Calendar> getChildCalendars()
141    {
142        return this.getChildren().stream()
143                .filter(Calendar.class::isInstance)
144                .map(Calendar.class::cast)
145                .toList();
146    }
147    
148    public List<CalendarEvent> getAllEvents()
149    {
150        return this.getChildren().stream()
151                    .filter(CalendarEvent.class::isInstance)
152                    .map(CalendarEvent.class::cast)
153                    .toList();
154    }
155    
156    public Map<CalendarEvent, List<CalendarEventOccurrence>> getEvents(ZonedDateTime startDate, ZonedDateTime endDate)
157    {
158        Map<CalendarEvent, List<CalendarEventOccurrence>> events = new HashMap<>();
159        
160        for (CalendarEvent event : getAllEvents())
161        {
162            List<CalendarEventOccurrence> occurences = event.getOccurrences(startDate, endDate);
163            if (!occurences.isEmpty())
164            {
165                events.put(event, occurences);
166            }
167        }
168        
169        return events;
170    }
171
172    public void setDescription(String desc)
173    {
174        setValue(CALENDAR_DESC, desc);
175    }
176
177    public void setColor(String color)
178    {
179        setValue(CALENDAR_COLOR, color); 
180    }
181    
182    public void setVisibility(CalendarVisibility visibility)
183    {
184        setValue(CALENDAR_VISIBILITY, visibility.name());
185    }
186
187    public void setWorkflowName(String workflowName)
188    {
189        setValue(CALENDAR_WORKFLOW_NAME, workflowName); 
190    }
191    
192    public void setTemplateDescription(String templateDesc)
193    {
194        setValue(CALENDAR_TEMPLATE_DESC, templateDesc);
195    }
196    
197    public boolean hasChildExplorerNodes() throws AmetysRepositoryException
198    {
199        try (AmetysObjectIterable<AmetysObject> children = getChildren())
200        {
201            for (AmetysObject child : children)
202            {
203                if (child instanceof ExplorerNode)
204                {
205                    return true;
206                }
207            }
208    
209            return false;
210        }
211    }
212    
213    public String getIcsUrlToken()
214    {
215        return getValue(CALENDAR_ICS_TOKEN);
216    }
217    
218    public void setIcsUrlToken(String token)
219    {
220        if (token != null)
221        {
222            setValue(CALENDAR_ICS_TOKEN, token);
223        }
224        else
225        {
226            removeValue(CALENDAR_ICS_TOKEN);
227        }
228    }
229}