/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.workspace; import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.Collections; import java.util.EventListener; import javax.swing.event.EventListenerList; import icy.file.FileUtil; import icy.system.thread.SingleProcessor; import icy.system.thread.ThreadUtil; import icy.workspace.WorkspaceLoader.WorkspaceLoaderEvent.WorkspaceLoaderEventType; /** * @author Stephane */ public class WorkspaceLoader { public static interface WorkspaceLoaderListener extends EventListener { public void workspaceLoaderChanged(WorkspaceLoaderEvent e); } public static class WorkspaceLoaderEvent { public enum WorkspaceLoaderEventType { RELOADED } private final WorkspaceLoaderEventType type; /** * @param type */ public WorkspaceLoaderEvent(WorkspaceLoaderEventType type) { super(); this.type = type; } /** * @return the type */ public WorkspaceLoaderEventType getType() { return type; } @Override public int hashCode() { return type.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof WorkspaceLoaderEvent) { final WorkspaceLoaderEvent e = (WorkspaceLoaderEvent) obj; return (type == e.getType()); } return super.equals(obj); } } public static final String WORKSPACE_PATH = "workspace"; public static final String EXT = ".xml"; /** * static class */ private static final WorkspaceLoader instance = new WorkspaceLoader(); /** * Loaded workspace list */ private ArrayList<Workspace> workspaces; /** * listeners */ private final EventListenerList listeners; /** * internals */ private final Runnable reloader; final SingleProcessor processor; private boolean initialized; /** * @param path */ private WorkspaceLoader() { super(); workspaces = new ArrayList<Workspace>(); listeners = new EventListenerList(); reloader = new Runnable() { @Override public void run() { reloadInternal(); } }; initialized = false; processor = new SingleProcessor(true, "Local Workspace Loader"); // don't load by default as we need Preferences to be ready first } public static void prepare() { if (!instance.initialized) { if (isLoading()) waitWhileLoading(); else reload(); } } /** * Reload the list of installed workspaces (workspaces present in the "workspaces" directory). * <br> * Asynchronous version. */ public static void reloadAsynch() { instance.processor.submit(instance.reloader); } /** * @deprecated Use {@link #reloadAsynch()} instead. */ @Deprecated public static void reload_asynch() { reloadAsynch(); } /** * Reload the list of installed workspaces (workspaces present in the "workspaces" directory) */ public static void reload() { reloadAsynch(); waitWhileLoading(); } /** * Reload the list of installed workspaces (workspaces present in the "workspaces" directory) */ void reloadInternal() { final ArrayList<Workspace> newWorkspaces = new ArrayList<Workspace>(); final File[] files = FileUtil.getFiles(new File(FileUtil.getGenericPath(WORKSPACE_PATH)), new FileFilter() { @Override public boolean accept(File file) { // only accept xml file return FileUtil.getFileExtension(file.getPath(), true).toLowerCase().equals(EXT); } }, true, false, false); for (File file : files) { final Workspace workspace = new Workspace(file); // don't load the specific system workspace if (!workspace.getName().equals(Workspace.WORKSPACE_SYSTEM_NAME)) { // empty workspace ? if (workspace.isEmpty()) { // don't show this message for default workspace // if (!workspace.getName().equals(Workspace.WORKSPACE_DEFAULT_NAME)) System.err.println("Empty workspace '" + workspace.getName() + "' is not loaded"); } else newWorkspaces.add(workspace); } } // sort list Collections.sort(newWorkspaces); // set workspace list workspaces = newWorkspaces; // notify change changed(); } /** * @return the workspaceList */ public static ArrayList<Workspace> getWorkspaces() { prepare(); synchronized (instance.workspaces) { // better to return a copy as we have async list loading return new ArrayList<Workspace>(instance.workspaces); } } /** * @return the loading flag */ public static boolean isLoading() { return instance.processor.isProcessing(); } /** * wait until loading completed */ public static void waitWhileLoading() { while (isLoading()) ThreadUtil.sleep(10); } public static boolean isLoaded(Workspace workspace) { return (getWorkspace(workspace.getName()) != null); } public static Workspace getWorkspace(String name) { prepare(); return Workspace.getWorkspace(getWorkspaces(), name); } private void changed() { initialized = true; // workspace list has changed fireEvent(new WorkspaceLoaderEvent(WorkspaceLoaderEventType.RELOADED)); } /** * Add a listener * * @param listener */ public static void addListener(WorkspaceLoaderListener listener) { synchronized (instance.listeners) { instance.listeners.add(WorkspaceLoaderListener.class, listener); } } /** * Remove a listener * * @param listener */ public static void removeListener(WorkspaceLoaderListener listener) { synchronized (instance.listeners) { instance.listeners.remove(WorkspaceLoaderListener.class, listener); } } /** * fire event */ private void fireEvent(WorkspaceLoaderEvent e) { for (WorkspaceLoaderListener listener : listeners.getListeners(WorkspaceLoaderListener.class)) listener.workspaceLoaderChanged(e); } }