001/*
002 *  Copyright 2022 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.repository.activities;
017
018import java.time.ZonedDateTime;
019import java.util.HashMap;
020import java.util.Map;
021
022import javax.jcr.RepositoryException;
023
024import org.ametys.core.observation.Event;
025import org.ametys.core.user.UserIdentity;
026import org.ametys.plugins.repository.AmetysObjectIterable;
027import org.ametys.plugins.repository.ModifiableTraversableAmetysObject;
028import org.ametys.plugins.repository.ObservationConstants;
029import org.ametys.runtime.model.type.ModelItemTypeConstants;
030
031/**
032 * Default implementation for an {@link ActivityHolder}
033 * This implementation is backed by a {@link ModifiableTraversableAmetysObject}
034 */
035public class DefaultActivityHolder implements ActivityHolder
036{
037    private ModifiableTraversableAmetysObject _rootCollection;
038    private DefaultActivityHolderFactory _activityHolderFactory;
039
040    /**
041     * Create a default {@link ActivityHolder}
042     * @param rootCollection the ametys object backing this activity holder
043     * @param factory the {@link DefaultActivityHolderFactory} which creates the AmetysObject
044     */
045    public DefaultActivityHolder(ModifiableTraversableAmetysObject rootCollection, DefaultActivityHolderFactory factory)
046    {
047        _rootCollection = rootCollection;
048        _activityHolderFactory = factory;
049    }
050
051    /**
052     * Returns the activity nodes
053     * @return The activities
054     * @throws RepositoryException if failed to get activity nodes
055     */
056    public AmetysObjectIterable<Activity> getActivities() throws RepositoryException
057    {
058        return _rootCollection.getChildren();
059    }
060    
061    public Activity addActivity(ActivityType type, Map<String, Object> parameters, String eventId) throws RepositoryException
062    {
063        return addActivity(ZonedDateTime.now(), type, parameters, _activityHolderFactory.getCurrentUser(), eventId);
064    }
065    
066    /**
067     * Add an activity to the activity holder
068     * @param date the date
069     * @param type the type
070     * @param parameters the parameters
071     * @param author the author
072     * @param eventId the id of the event
073     * @return the activity
074     * @throws RepositoryException when an error occurred
075     */
076    public Activity addActivity(ZonedDateTime date, ActivityType type, Map<String, Object> parameters, UserIdentity author, String eventId) throws RepositoryException
077    {
078        String activityName = ACTIVITY_NAME_PREFIX + date.format(JCR_UTC_FORMAT);
079        
080        Activity activity = _rootCollection.createChild(activityName, ActivityFactory.NODE_TYPE);
081        
082        // Date
083        activity.setValue(ActivityFactory.DATE, date, ModelItemTypeConstants.DATETIME_TYPE_ID);
084        
085        // Type
086        activity.setValue(ActivityFactory.TYPE, eventId, ModelItemTypeConstants.STRING_TYPE_ID);
087        
088        // Author
089        // TODO GG we should use a constant here
090        activity.setValue(ActivityFactory.AUTHOR, author, "user");
091        
092        type.setAdditionalActivityData(activity, parameters);
093        _rootCollection.saveChanges();
094        
095        _notifyObserver(activity);
096        
097        return activity;
098    }
099    
100    private void _notifyObserver(Activity activity)
101    {
102        Map<String, Object> params = new HashMap<>();
103        // Provide the activity and the id for both sync and async observer
104        params.put(ObservationConstants.ARGS_ACTIVITY, activity);
105        params.put(ObservationConstants.ARGS_ACTIVITY_ID, activity.getId());
106        Event event = new Event(ObservationConstants.EVENT_ACTIVITY_CREATED, activity.getAuthor(), params);
107        _activityHolderFactory.getObservationManager().notify(event);
108    }
109}