package de.persosim.simulator.perso; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.StringWriter; import org.globaltester.lib.xstream.XstreamFactory; import org.globaltester.logging.BasicLogger; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.core.util.CompositeClassLoader; import com.thoughtworks.xstream.io.xml.DomDriver; import de.persosim.simulator.Activator; import de.persosim.simulator.perso.xstream.CommandProcessorConverter; import de.persosim.simulator.perso.xstream.ECParameterSpecConverter; import de.persosim.simulator.perso.xstream.EncodedByteArrayConverter; import de.persosim.simulator.perso.xstream.KeyConverter; import de.persosim.simulator.perso.xstream.KeyPairConverter; import de.persosim.simulator.perso.xstream.ProtocolConverter; import de.persosim.simulator.perso.xstream.TlvConverter; /** * This class provides methods that serializes/deserializes personalization objects * * @author jgoeke * */ public class PersonalizationFactory { /** * This method serializes the personalization object and writes it into a given writer * @param pers object which contains the whole personalization * @param writer object which will be filled with the serialized personalization */ public static void marshal(Object pers, StringWriter writer) throws NullPointerException { if (pers == null) { throw new NullPointerException ("Personalization object is null!"); } XStream xstream = getXStream(); xstream.autodetectAnnotations(true); StringWriter xmlWriter = new StringWriter(); xstream.toXML (pers, xmlWriter); //TODO find a alternative to suppress the class attribute, created by xStream, if element is a type of Key String xmlRepresentation = xmlWriter.toString(); xmlRepresentation = xmlRepresentation.replaceAll("class=\"org.*[Kk]ey\"", ""); writer.append(xmlRepresentation); } public static void marshal (Object pers, String path) { FileWriter fileWriter; try { fileWriter = new FileWriter (path); marshal (pers, fileWriter); } catch (IOException e) { e.printStackTrace(); } } public static void marshal (Object pers, FileWriter file) throws NullPointerException { StringWriter writer = new StringWriter(); marshal (pers, writer); if (file == null) { throw new NullPointerException ("FileWriter object is null!"); } try { file.write (writer.toString()); file.flush(); file.close(); } catch (IOException e) { e.printStackTrace(); } } /** * This method deserializes the personalization object * @param reader object which the personalization * @return a object with a deserialized personalization */ public static Object unmarshal (Reader reader) throws NullPointerException { if (reader == null) { throw new NullPointerException ("Reader object is null!"); } XStream xstream = getXStream(); return xstream.fromXML (reader); } public static Object unmarshal (String path) throws FileNotFoundException { File xmlFile = new File(path); if (xmlFile.exists()) { BasicLogger.log(PersonalizationFactory.class, "File at " + path + " found"); } else{ throw new FileNotFoundException ("File at " + path + " NOT found"); } return unmarshal (new FileReader(path)); } /** * This method creates a xStream object with all necessary configuration * @return a xStream object */ private static XStream getXStream() { DomDriver domDriver = new DomDriver("UTF-8"); ShouldSerializeMemberImpl ssm = new ShouldSerializeMemberImpl(); XStream xstream = XstreamFactory.get(domDriver, ssm, PersonalizationFactory.class.getClassLoader()); xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES); xstream.setMode(XStream.ID_REFERENCES); xstream.registerConverter(new EncodedByteArrayConverter()); xstream.registerConverter(new ProtocolConverter()); xstream.registerConverter(new KeyPairConverter()); xstream.registerConverter(new ECParameterSpecConverter()); xstream.registerConverter(new KeyConverter()); xstream.registerConverter(new TlvConverter()); xstream.registerConverter(new CommandProcessorConverter()); // get converters as services if (Activator.getContext() != null) { ServiceTracker<Converter, Converter> serviceTracker = new ServiceTracker<Converter, Converter>( Activator.getContext(), Converter.class.getName(), null); serviceTracker.open(); ServiceReference<Converter>[] allServiceReferences = serviceTracker.getServiceReferences(); StringBuilder availableConverters = new StringBuilder(); availableConverters.append("Available xstream converter services:"); if (allServiceReferences != null) { for (ServiceReference<Converter> serviceReference : allServiceReferences) { Converter service = serviceTracker.getService(serviceReference); availableConverters.append("\n " + service.getClass() + " from bundle: " + serviceReference.getBundle().getSymbolicName()); ((CompositeClassLoader) xstream.getClassLoader()).add(service.getClass().getClassLoader()); xstream.registerConverter(service, 10); } } else { availableConverters.append(" none"); } serviceTracker.close(); BasicLogger.log(PersonalizationFactory.class, availableConverters.toString()); } else { BasicLogger.log(PersonalizationFactory.class, "Could not get the bundle context, no Converter services added to XStream"); } return xstream; } }