package org.geoserver.notification.common; import java.util.List; import org.geoserver.notification.common.sender.NotificationSender; import org.geoserver.platform.GeoServerExtensions; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.mapper.Mapper; public class SenderXStreamInitializer implements NotificationXStreamInitializer { /** * Alias for sender tag of in xml configuration */ public String name; /** * Class to use for sender with filed 'name' */ public Class<? extends NotificationSender> clazz; /** * Define an alias for the {@link DefaultNotificationProcessor#sender sender}<br> * Define a class for the {@link NotificationSender}<br> * An example of sender configuration section in notifier.xml is: * * <pre> * {@code * <genericProcessor> * <fanoutSender> * ... * </fanoutSender> * </genericProcessor> * } * </pre> * * @param xs XStream object * */ public SenderXStreamInitializer(String name, Class<? extends NotificationSender> clazz) { super(); this.name = name; this.clazz = clazz; } @Override public void init(XStream xs) { xs.aliasAttribute(DefaultNotificationProcessor.class, "sender", name); xs.registerLocalConverter(DefaultNotificationProcessor.class, "sender", new SenderConverter(xs.getMapper(), xs.getReflectionProvider(), this)); } /** * * @author Alessio Fabiani, GeoSolutions S.A.S. * */ static public class SenderConverter extends ReflectionConverter { private SenderXStreamInitializer senderXStreamInitializer; /** * @param mapper * @param reflectionProvider * @param senderXStreamInitializer */ public SenderConverter(Mapper mapper, ReflectionProvider reflectionProvider, SenderXStreamInitializer senderXStreamInitializer) { super(mapper, reflectionProvider); this.senderXStreamInitializer = senderXStreamInitializer; } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public boolean canConvert(Class clazz) { return clazz.isAssignableFrom(senderXStreamInitializer.clazz); } @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { NotificationSender sender = null; String nodeName = reader.getNodeName(); List<SenderXStreamInitializer> serializers = GeoServerExtensions.extensions(SenderXStreamInitializer.class); for(SenderXStreamInitializer serializer : serializers) { if (serializer.name.equals(nodeName)) { try { sender = serializer.clazz.newInstance(); sender = (NotificationSender) context.convertAnother(sender, serializer.clazz); break; } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } } return sender; } } }