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