001/* 002 * Copyright 2016 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.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint; 024 025/** 026 * This class is in charge of loading the various {@link ActivityType}. 027 * It also allows to communicate with them for the retrieval of activity in JSON 028 */ 029public class ActivityTypeExtensionPoint extends AbstractThreadSafeComponentExtensionPoint<ActivityType> 030{ 031 /** The Avalon Role */ 032 public static final String ROLE = ActivityTypeExtensionPoint.class.getName(); 033 034 /** 035 * Merge activities 036 * @param initialActivities The activities to merge 037 * @return The merged activities 038 */ 039 public List<Map<String, Object>> mergeActivities(List<Activity> initialActivities) 040 { 041 List<Map<String, Object>> mergedActivities = new ArrayList<>(); 042 043 List<Activity> activitiesToMerge = new ArrayList<>(initialActivities); 044 Map<String, List<Activity>> mergeableActivities = new HashMap<>(); 045 046 for (Activity activity : initialActivities) 047 { 048 String activityId = activity.getId(); 049 050 List<Activity> clonedActivities = new ArrayList<>(activitiesToMerge); 051 for (Activity clonedActivity : clonedActivities) 052 { 053 String clonedActivityId = clonedActivity.getId(); 054 055 if (!activityId.equals(clonedActivityId)) 056 { 057 ActivityType activityType = activity.getActivityType(); 058 ActivityType clonedActivityType = activity.getActivityType(); 059 060 if (activityType == clonedActivityType && activityType.isMergeable(activity, clonedActivity)) 061 { 062 mergeableActivities.computeIfAbsent(activityId, str -> new ArrayList<>()).add(clonedActivity); 063 064 // The events were merged : no need to re-process them 065 activitiesToMerge.remove(activity); 066 activitiesToMerge.remove(clonedActivity); 067 } 068 } 069 else 070 { 071 mergeableActivities.computeIfAbsent(activityId, str -> new ArrayList<>()).add(activity); 072 } 073 } 074 } 075 076 for (List<Activity> acts : mergeableActivities.values()) 077 { 078 // FIXME GG not sure it's fine to take the first one. Quite random 079 ActivityType eventType = acts.get(0).getActivityType(); 080 mergedActivities.add(eventType.mergeActivities(acts)); 081 } 082 083 return mergedActivities; 084 } 085 086 /** 087 * Returns the first {@link ActivityType} matching the provided event id 088 * @param eventId the id of the event 089 * @return The event type 090 */ 091 public ActivityType getActivityType(String eventId) 092 { 093 for (String extensionId : getExtensionsIds()) 094 { 095 ActivityType eventType = getExtension(extensionId); 096 if (eventType.getSupportedEventTypes().keySet().contains(eventId)) 097 { 098 return eventType; 099 } 100 } 101 102 throw new ActivityTypeProcessingException("There is no ActivityType corresponding with the id '" + eventId + "'."); 103 } 104}