blob: 39117e9d52fe03d977265be6e12a04b26dec86f9 [file] [log] [blame]
/*******************************************************************************
* 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>();
}
}
}