Java tutorial
/******************************************************************************* * Copyright (C) 2007 The University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ******************************************************************************/ package net.sf.taverna.t2.workbench.file.impl; import static org.apache.commons.collections.map.LazyMap.decorate; import static org.apache.commons.lang.ClassUtils.getAllInterfaces; import static org.apache.commons.lang.ClassUtils.getAllSuperclasses; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler; import net.sf.taverna.t2.workbench.file.FileType; import org.apache.commons.collections.Factory; // TODO: Cache lookups / build one massive structure public class DataflowPersistenceHandlerRegistry { private static final MapFactory MAP_FACTORY = new MapFactory(); private static final SetFactory SET_FACTORY = new SetFactory(); @SuppressWarnings("unchecked") protected static List<Class<?>> findAllParentClasses(final Class<?> sourceClass) { List<Class<?>> superClasses = new ArrayList<>(); superClasses.add(sourceClass); superClasses.addAll(getAllSuperclasses(sourceClass)); superClasses.addAll(getAllInterfaces(sourceClass)); return superClasses; } private Map<Class<?>, Set<DataflowPersistenceHandler>> openClassToHandlers; private Map<Class<?>, Set<FileType>> openClassToTypes; private Map<FileType, Map<Class<?>, Set<DataflowPersistenceHandler>>> openFileClassToHandler; private Map<FileType, Set<DataflowPersistenceHandler>> openFileToHandler; private Map<Class<?>, Set<DataflowPersistenceHandler>> saveClassToHandlers; private Map<Class<?>, Set<FileType>> saveClassToTypes; private Map<FileType, Map<Class<?>, Set<DataflowPersistenceHandler>>> saveFileClassToHandler; private Map<FileType, Set<DataflowPersistenceHandler>> saveFileToHandler; private List<DataflowPersistenceHandler> dataflowPersistenceHandlers; public DataflowPersistenceHandlerRegistry() { } public Set<FileType> getOpenFileTypes() { return getOpenFileClassToHandler().keySet(); } public Set<FileType> getOpenFileTypesFor(Class<?> sourceClass) { Set<FileType> fileTypes = new LinkedHashSet<>(); for (Class<?> candidateClass : findAllParentClasses(sourceClass)) fileTypes.addAll(getOpenClassToTypes().get(candidateClass)); return fileTypes; } public Set<DataflowPersistenceHandler> getOpenHandlersFor(Class<? extends Object> sourceClass) { Set<DataflowPersistenceHandler> handlers = new LinkedHashSet<>(); for (Class<?> candidateClass : findAllParentClasses(sourceClass)) handlers.addAll(getOpenClassToHandlers().get(candidateClass)); return handlers; } public Set<DataflowPersistenceHandler> getOpenHandlersFor(FileType fileType, Class<? extends Object> sourceClass) { Set<DataflowPersistenceHandler> handlers = new LinkedHashSet<>(); for (Class<?> candidateClass : findAllParentClasses(sourceClass)) handlers.addAll(getOpenFileClassToHandler().get(fileType).get(candidateClass)); return handlers; } public Set<DataflowPersistenceHandler> getOpenHandlersForType(FileType fileType) { return getOpenFileToHandler().get(fileType); } public synchronized Set<DataflowPersistenceHandler> getOpenHandlersForType(FileType fileType, Class<?> sourceClass) { Set<DataflowPersistenceHandler> handlers = new LinkedHashSet<>(); for (Class<?> candidateClass : findAllParentClasses(sourceClass)) handlers.addAll(getOpenFileClassToHandler().get(fileType).get(candidateClass)); return handlers; } public Set<FileType> getSaveFileTypes() { return getSaveFileClassToHandler().keySet(); } public Set<FileType> getSaveFileTypesFor(Class<?> destinationClass) { Set<FileType> fileTypes = new LinkedHashSet<>(); for (Class<?> candidateClass : findAllParentClasses(destinationClass)) fileTypes.addAll(getSaveClassToTypes().get(candidateClass)); return fileTypes; } public Set<DataflowPersistenceHandler> getSaveHandlersFor(Class<? extends Object> destinationClass) { Set<DataflowPersistenceHandler> handlers = new LinkedHashSet<>(); for (Class<?> candidateClass : findAllParentClasses(destinationClass)) handlers.addAll(getSaveClassToHandlers().get(candidateClass)); return handlers; } public Set<DataflowPersistenceHandler> getSaveHandlersForType(FileType fileType, Class<?> destinationClass) { Set<DataflowPersistenceHandler> handlers = new LinkedHashSet<>(); for (Class<?> candidateClass : findAllParentClasses(destinationClass)) handlers.addAll(getSaveFileClassToHandler().get(fileType).get(candidateClass)); return handlers; } @SuppressWarnings({ "unchecked", "rawtypes" }) private synchronized void createCollections() { openFileClassToHandler = decorate(new HashMap(), MAP_FACTORY); openFileToHandler = decorate(new HashMap(), SET_FACTORY); openClassToTypes = decorate(new HashMap(), SET_FACTORY); openClassToHandlers = decorate(new HashMap(), SET_FACTORY); saveFileClassToHandler = decorate(new HashMap(), MAP_FACTORY); saveFileToHandler = decorate(new HashMap(), SET_FACTORY); saveClassToTypes = decorate(new HashMap(), SET_FACTORY); saveClassToHandlers = decorate(new HashMap(), SET_FACTORY); } private Map<Class<?>, Set<DataflowPersistenceHandler>> getOpenClassToHandlers() { return openClassToHandlers; } private synchronized Map<Class<?>, Set<FileType>> getOpenClassToTypes() { return openClassToTypes; } private synchronized Map<FileType, Map<Class<?>, Set<DataflowPersistenceHandler>>> getOpenFileClassToHandler() { return openFileClassToHandler; } private Map<FileType, Set<DataflowPersistenceHandler>> getOpenFileToHandler() { return openFileToHandler; } private Map<Class<?>, Set<DataflowPersistenceHandler>> getSaveClassToHandlers() { return saveClassToHandlers; } private synchronized Map<Class<?>, Set<FileType>> getSaveClassToTypes() { return saveClassToTypes; } private synchronized Map<FileType, Map<Class<?>, Set<DataflowPersistenceHandler>>> getSaveFileClassToHandler() { return saveFileClassToHandler; } /** * Bind method for SpringDM. * * @param service * @param properties */ public void update(Object service, Map<?, ?> properties) { if (dataflowPersistenceHandlers != null) updateColletions(); } public synchronized void updateColletions() { createCollections(); for (DataflowPersistenceHandler handler : dataflowPersistenceHandlers) { for (FileType openFileType : handler.getOpenFileTypes()) { Set<DataflowPersistenceHandler> set = openFileToHandler.get(openFileType); set.add(handler); for (Class<?> openClass : handler.getOpenSourceTypes()) { openFileClassToHandler.get(openFileType).get(openClass).add(handler); openClassToTypes.get(openClass).add(openFileType); } } for (Class<?> openClass : handler.getOpenSourceTypes()) openClassToHandlers.get(openClass).add(handler); for (FileType saveFileType : handler.getSaveFileTypes()) { saveFileToHandler.get(saveFileType).add(handler); for (Class<?> saveClass : handler.getSaveDestinationTypes()) { saveFileClassToHandler.get(saveFileType).get(saveClass).add(handler); saveClassToTypes.get(saveClass).add(saveFileType); } } for (Class<?> openClass : handler.getSaveDestinationTypes()) saveClassToHandlers.get(openClass).add(handler); } } public void setDataflowPersistenceHandlers(List<DataflowPersistenceHandler> dataflowPersistenceHandlers) { this.dataflowPersistenceHandlers = dataflowPersistenceHandlers; } private static class MapFactory implements Factory { @Override @SuppressWarnings("rawtypes") public Object create() { return decorate(new HashMap(), SET_FACTORY); } } private static class SetFactory implements Factory { @Override public Object create() { return new LinkedHashSet<Object>(); } } }