/*
* 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 icy.network.NetworkUtil;
import icy.network.URLUtil;
import icy.preferences.RepositoryPreferences;
import icy.preferences.RepositoryPreferences.RepositoryInfo;
import icy.system.IcyExceptionHandler;
import icy.util.StringUtil;
import icy.util.XMLUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EventListener;
import javax.swing.event.EventListenerList;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/**
* @author Stephane
*/
public class WorkspaceRepositoryLoader
{
public static interface WorkspaceRepositoryLoaderListener extends EventListener
{
public void workspaceRepositeryLoaderChanged();
}
private class LoadRunner extends Thread
{
public LoadRunner()
{
super("Online workspace loader");
}
@Override
public void run()
{
// no Internet connection ?
if (!NetworkUtil.hasInternetAccess())
{
failed = true;
return;
}
final ArrayList<Workspace> newWorkspaces = new ArrayList<Workspace>();
failed = false;
try
{
final ArrayList<RepositoryInfo> repositories = RepositoryPreferences.getRepositeries();
// load online workspace from all active repositories
for (RepositoryInfo repoInfo : repositories)
{
if (interrupted())
return;
if (repoInfo.isEnabled())
{
final ArrayList<Workspace> workspacesRepos = loadInternal(repoInfo);
if (workspacesRepos == null)
{
failed = true;
return;
}
newWorkspaces.addAll(workspacesRepos);
}
}
// sort list
Collections.sort(newWorkspaces);
synchronized (workspaces)
{
workspaces = newWorkspaces;
}
}
catch (Exception e)
{
IcyExceptionHandler.showErrorMessage(e, true);
failed = true;
return;
}
changed();
}
}
private static final String ID_ROOT = "workspaces";
private static final String ID_WORKSPACE = "workspace";
private static final String ID_PATH = "path";
/**
* static class
*/
private static final WorkspaceRepositoryLoader instance = new WorkspaceRepositoryLoader();
/**
* Online workspace list
*/
ArrayList<Workspace> workspaces;
/**
* internal
*/
boolean failed;
private LoadRunner loadRunner;
/**
* listeners
*/
private final EventListenerList listeners;
/**
* static class
*/
private WorkspaceRepositoryLoader()
{
super();
workspaces = new ArrayList<Workspace>();
listeners = new EventListenerList();
failed = false;
// initial loading
startLoad();
}
/**
* Return the workspaces file list from a repository URL
*/
public static ArrayList<String> getWorkspaceFiles(RepositoryInfo repos)
{
final ArrayList<String> result = new ArrayList<String>();
final Document document = XMLUtil.loadDocument(repos.getLocation(), repos.getAuthenticationInfo(), true);
if (document != null)
{
// get workspaces node
final Node workspacesNode = XMLUtil.getElement(document.getDocumentElement(), ID_ROOT);
// workspaces node found
if (workspacesNode != null)
{
final ArrayList<Node> nodes = XMLUtil.getChildren(workspacesNode, ID_WORKSPACE);
for (Node node : nodes)
{
final String path = XMLUtil.getElementValue(node, ID_PATH, "");
if (!StringUtil.isEmpty(path))
result.add(path);
}
}
}
else
{
if (!NetworkUtil.hasInternetAccess())
System.out.println("You are not connected to internet.");
else
System.out.println("Can't access repository '" + repos.getName() + "'");
}
return result;
}
/**
* Start loading process
*/
private void startLoad()
{
loadRunner = new LoadRunner();
loadRunner.start();
}
/**
* Reload all online workspaces from all active repositories (old list is cleared)
*/
public static void reload()
{
// request interrupt
instance.loadRunner.interrupt();
// We don't need to wait... can make the preferences panel to lag on validation
// // wait for end processing
// try
// {
// instance.loadRunner.join();
// }
// catch (InterruptedException e)
// {
// // ignore
// }
// start it again
instance.startLoad();
}
/**
* Load and return the list of online workspaces located at specified repository url
*/
ArrayList<Workspace> loadInternal(RepositoryInfo repos)
{
final ArrayList<String> paths = getWorkspaceFiles(repos);
// error while retrieving paths ?
if (paths == null)
{
if (!NetworkUtil.hasInternetAccess())
System.out.println("You are not connected to internet.");
else
System.out.println("Can't access repository '" + repos.getName() + "'");
return null;
}
final ArrayList<Workspace> result = new ArrayList<Workspace>();
for (String path : paths)
{
try
{
final Workspace workspace = new Workspace(URLUtil.getURL(path), repos);
if (!workspace.isEmpty())
result.add(workspace);
}
catch (Exception e)
{
System.err.println("WorkspaceRepositoryLoader.load('" + repos.getLocation() + "') error :");
IcyExceptionHandler.showErrorMessage(e, false);
}
}
return result;
}
/**
* @return the workspaceList
*/
public static ArrayList<Workspace> getWorkspaces()
{
synchronized (instance.workspaces)
{
return new ArrayList<Workspace>(instance.workspaces);
}
}
public static Workspace getWorkspace(String className)
{
synchronized (instance.workspaces)
{
return Workspace.getWorkspace(instance.workspaces, className);
}
}
/**
* Return the workspace list from the specified repository
*/
public static ArrayList<Workspace> getWorkspaces(RepositoryInfo repos)
{
final ArrayList<Workspace> result = new ArrayList<Workspace>();
synchronized (instance.workspaces)
{
for (Workspace workspace : instance.workspaces)
if (workspace.getRepository().equals(repos))
result.add(workspace);
}
return result;
}
/**
* @return the loaded
*/
public static boolean isLoading()
{
return instance.loadRunner.isAlive();
}
/**
* wait until loading completed
*/
public static void waitWhileLoading()
{
try
{
instance.loadRunner.join();
}
catch (InterruptedException e)
{
// ignore
}
}
/**
* return true if an error occurred during the workspace loading process
*/
public static boolean failed()
{
return instance.failed;
}
/**
* workspace list has changed
*/
void changed()
{
fireEvent();
}
/**
* Add a listener
*
* @param listener
*/
public static void addListener(WorkspaceRepositoryLoaderListener listener)
{
synchronized (instance.listeners)
{
instance.listeners.add(WorkspaceRepositoryLoaderListener.class, listener);
}
}
/**
* Remove a listener
*
* @param listener
*/
public static void removeListener(WorkspaceRepositoryLoaderListener listener)
{
synchronized (instance.listeners)
{
instance.listeners.remove(WorkspaceRepositoryLoaderListener.class, listener);
}
}
/**
* fire event
*/
private void fireEvent()
{
for (WorkspaceRepositoryLoaderListener listener : listeners
.getListeners(WorkspaceRepositoryLoaderListener.class))
listener.workspaceRepositeryLoaderChanged();
}
}