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