// Copyright 2003-2006, FreeHEP. package org.freehep.util.export; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.imageio.spi.RegisterableService; import javax.imageio.spi.ServiceRegistry; import org.freehep.util.Service; /** * * @author Mark Donszelmann * @version $Id: ExportFileTypeRegistry.java 12746 2007-06-12 22:18:45Z duns $ */ public class ExportFileTypeRegistry { private static ExportFileTypeRegistry registry; private static ClassLoader loader; private ServiceRegistry service; private List/*<ExportFileType>*/ extraTypes; private static final Collection categories = new ArrayList(2); static { categories.add(ExportFileType.class); categories.add(RegisterableService.class); } private ExportFileTypeRegistry() { service = new ServiceRegistry(categories.iterator()); extraTypes = new ArrayList(); } public static synchronized ExportFileTypeRegistry getDefaultInstance(ClassLoader loader) { if ((loader != null) && (loader != ExportFileTypeRegistry.loader)) { if (ExportFileTypeRegistry.loader != null) throw new RuntimeException(ExportFileTypeRegistry.class.getName() + ": Different classloader was already used in getDefaultInstance"); ExportFileTypeRegistry.loader = loader; } if (registry == null) { registry = new ExportFileTypeRegistry(); // NOTE: not in constructor to avoid recursive calls. If such call comes in // as a result of something on the classpath needing the registry inside // the onRegistration call. Such call would just return the already created // registry. addApplicationClasspathExportFileTypes(registry); } return registry; } /** * Returns a list of all registered ExportFileTypes in the order in which * they are found in jar files on the classpath. */ public List get() { return get(null); } /** * Returns a list of all registered ExportFileTypes in the order in which * they are found in jar files on the classpath, followed by all the extra * registered ExportFileTypes as long as they do not duplicate any * ExportFileType in the list. The list is for a particular * format, or all if format is null. */ public List/*<ExportFileType>*/ get(String format) { List export = new ArrayList(); // add all ExportFileTypes found in service addExportFileTypeToList(export, format, service.getServiceProviders(ExportFileType.class, true)); // add all ExportFileTypes on extraTypes addExportFileTypeToList(export, format, extraTypes.iterator()); return export; } /** * Adds ExportFile. * * @param exportFileType */ public void add(ExportFileType exportFileType) { extraTypes.add(exportFileType); } private void addExportFileTypeToList(List list, String format, Iterator iterator) { while (iterator.hasNext()) { ExportFileType type = (ExportFileType)iterator.next(); if (format == null) { if (!list.contains(type)) { list.add(type); } } else { String[] ext = type.getExtensions(); for (int i=0; i<ext.length; i++) { if (ext[i].equalsIgnoreCase(format)) { if (!list.contains(type)) { list.add(type); } break; } } } } } private static void addApplicationClasspathExportFileTypes(ExportFileTypeRegistry registry) { ClassLoader classLoader = (loader != null) ? loader : Thread.currentThread().getContextClassLoader(); Iterator iterator = categories.iterator(); while (iterator.hasNext()) { Class category = (Class)iterator.next(); Iterator providers = Service.providers(category, classLoader).iterator(); Object previous = null; while (providers.hasNext()) { Object current = providers.next(); registry.service.registerServiceProvider(current); if (previous != null) { registry.service.setOrdering(category, previous, current); } previous = current; } } } }