/* * Part of the CCNx Java Library. * * Copyright (C) 2008-2012 Palo Alto Research Center, Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. You should have received * a copy of the GNU Lesser General Public License along with this library; * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, * Fifth Floor, Boston, MA 02110-1301 USA. */ package org.ccnx.ccn.impl.encoding; import java.util.HashMap; import java.util.logging.Level; import org.ccnx.ccn.config.SystemConfiguration; import org.ccnx.ccn.impl.support.Log; /** * Factory class that given a string codec name, returns the XMLEncoder and XMLDecoder * that handle that codec. Allows new codecs to be registered on the fly for extensibility. */ public class XMLCodecFactory { protected static String _defaultCodec = null; static { // Make sure this happens before any registrations _registeredEncoders = new HashMap<String,Class<? extends XMLEncoder>>(); _registeredDecoders = new HashMap<String,Class<? extends XMLDecoder>>(); // Register standard system encoders and decoders here. If // registration placed in static initializers of their own class, // those aren't called till the classes are loaded, which doesn't // happen till we make one -- which we can't do till they're // registered. Chicken and egg... avoid by doing it here. XMLCodecFactory.registerEncoder(TextXMLCodec.codecName(), TextXMLEncoder.class); XMLCodecFactory.registerDecoder(TextXMLCodec.codecName(), TextXMLDecoder.class); XMLCodecFactory.registerDecoder(BinaryXMLCodec.codecName(), BinaryXMLDecoder.class); XMLCodecFactory.registerEncoder(BinaryXMLCodec.codecName(), BinaryXMLEncoder.class); } protected static HashMap<String,Class<? extends XMLEncoder>> _registeredEncoders; protected static HashMap<String,Class<? extends XMLDecoder>> _registeredDecoders; public static void registerEncoder(String name, Class<? extends XMLEncoder> encoderClass) { _registeredEncoders.put(name, encoderClass); } public static void registerDecoder(String name, Class<? extends XMLDecoder> decoderClass) { _registeredDecoders.put(name, decoderClass); } public static void setDefaultCodec(String name) { if ((null == getEncoderClass(name)) || (null == getDecoderClass(name))) { Log.warning(Log.FAC_ENCODING, "Cannot set unknown codec " + name + " as default XML codec."); throw new IllegalArgumentException(name + " must be a registered codec!"); } _defaultCodec = name; } /** * If default codec has been set for this runtime using setDefaultCodec, * use that value. If not, go to SystemConfiguration to get either the * command-line value if present or the compiled-in default. * @return */ public static String getDefaultCodecName() { if (null != _defaultCodec) return _defaultCodec; return SystemConfiguration.getDefaultEncoding(); } /** * Get instance of default encoder. * @return */ public static XMLEncoder getEncoder() { return getEncoder(null); } /** * Get an instance of the specified encoder. * @param codecName * @return */ public static XMLEncoder getEncoder(String codecName) { Class<? extends XMLEncoder> encoderClass = getEncoderClass(codecName); if (null == encoderClass) { return null; } // Have the class. Now need to use the default constructor. XMLEncoder encoder = null; try { encoder = encoderClass.newInstance(); } catch (Exception e) { Log.warning("Unexpected error: cannot create instance of encoder class " + encoderClass.getName()); Log.logStackTrace(Level.WARNING, e); throw new RuntimeException("Unexpected error: cannot create instance of encoder class " + encoderClass.getName(), e); } return encoder; } /** * Get instance of default decoder. */ public static XMLDecoder getDecoder() { return getDecoder(null); } /** * Get instance of specified decoder. * @param codecName * @return */ public static XMLDecoder getDecoder(String codecName) { Class<? extends XMLDecoder> decoderClass = getDecoderClass(codecName); if (null == decoderClass) { return null; } // Have the class. Now need to use the default constructor. XMLDecoder decoder = null; try { decoder = decoderClass.newInstance(); } catch (Exception e) { Log.warning("Unexpected error: cannot create instance of decoder class " + decoderClass.getName()); Log.logStackTrace(Level.WARNING, e); throw new RuntimeException("Unexpected error: cannot create instance of decoder class " + decoderClass.getName(), e); } return decoder; } public static Class<? extends XMLEncoder> getEncoderClass(String codecName) { if (null == codecName) return getDefaultEncoderClass(); return _registeredEncoders.get(codecName); } public static Class<? extends XMLDecoder> getDecoderClass(String codecName) { if (null == codecName) return getDefaultDecoderClass(); return _registeredDecoders.get(codecName); } public static Class<? extends XMLEncoder> getDefaultEncoderClass() { return getEncoderClass(getDefaultCodecName()); } public static Class<? extends XMLDecoder> getDefaultDecoderClass() { return getDecoderClass(getDefaultCodecName()); } }