001/* 002 * Copyright 2025 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.cms.trash.observer; 017 018import java.lang.reflect.ParameterizedType; 019import java.util.HashMap; 020import java.util.Map; 021 022import org.apache.avalon.framework.service.ServiceException; 023import org.apache.avalon.framework.service.ServiceManager; 024import org.apache.avalon.framework.service.Serviceable; 025 026import org.ametys.cms.ObservationConstants; 027import org.ametys.core.observation.Event; 028import org.ametys.core.observation.ObservationManager; 029import org.ametys.core.observation.Observer; 030import org.ametys.plugins.repository.AmetysObject; 031import org.ametys.plugins.repository.AmetysObjectResolver; 032import org.ametys.plugins.repository.trash.TrashableAmetysObject; 033 034/** 035 * Abstract observer to send added notification of each object restored by the trash. 036 * @param <T> The type of the restored object 037 */ 038@SuppressWarnings("unchecked") 039public abstract class AbstractAmetysObjectAddedObserver<T extends TrashableAmetysObject> implements Observer, Serviceable 040{ 041 private AmetysObjectResolver _resolver; 042 private ObservationManager _observationManager; 043 044 private Class<T> _type; 045 { 046 // Get the <T> class by going up in the implementation until the superclass is this abstract class (AbstractElementType) 047 Class c = this.getClass(); 048 while (!c.getSuperclass().equals(AbstractAmetysObjectAddedObserver.class)) 049 { 050 c = c.getSuperclass(); 051 } 052 053 // The super class is now AbstractElementType, which is Parameterized, so we can get the type arguments 054 _type = (Class<T>) ((ParameterizedType) c.getGenericSuperclass()).getActualTypeArguments()[0]; 055 } 056 057 public void service(ServiceManager manager) throws ServiceException 058 { 059 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 060 _observationManager = (ObservationManager) manager.lookup(ObservationManager.ROLE); 061 } 062 063 public int getPriority() 064 { 065 // Should be launch soon in the process 066 return 500; 067 } 068 069 public boolean supports(Event event) 070 { 071 return event.getId().equals(ObservationConstants.EVENT_TRASH_RESTORED); 072 } 073 074 public void observe(Event event, Map<String, Object> transientVars) throws Exception 075 { 076 T ametysObject = _getAmetysObject(event); 077 if (ametysObject != null) 078 { 079 _observationManager.notify(new Event(getEventId(), event.getIssuer(), getEventParams(ametysObject))); 080 } 081 } 082 083 /** 084 * Get event identifier to notify. 085 * @return the event id 086 */ 087 protected abstract String getEventId(); 088 089 /** 090 * Get the event params to send in the notification. 091 * @param ametysObject The Ametys object on which the event is send 092 * @return the event params as a map 093 */ 094 protected Map<String, Object> getEventParams(T ametysObject) 095 { 096 Map<String, Object> eventParams = new HashMap(); 097 098 eventParams.put(TrashObserverHelper.ARGS_ORIGIN_RESTORED, true); 099 eventParams.putAll(getAdditionalEventParams(ametysObject)); 100 101 return eventParams; 102 } 103 104 /** 105 * Get the additional event params specific to the child observer to send in the notification. 106 * @param ametysObject The Ametys object on which the event is send 107 * @return the event params as a map 108 */ 109 protected abstract Map<String, Object> getAdditionalEventParams(T ametysObject); 110 111 /** 112 * Get the Ametys object and type it from the event arguments. 113 * @param event the event 114 * @return the typed Ametys object or null if not found or not of the parameterized type 115 */ 116 private T _getAmetysObject(Event event) 117 { 118 String ametysObjectId = (String) event.getArguments().get(ObservationConstants.ARGS_AMETYS_OBJECT_ID); 119 AmetysObject ametysObject = _resolver.resolveById(ametysObjectId); 120 return _type.isInstance(ametysObject) ? _type.cast(ametysObject) : null; 121 } 122}