/*******************************************************************************
* Copyright (c) 2005 RadRails.org and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.radrails.db.core;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.radrails.rails.core.IRailsConstants;
/**
* Singleton class that manages all of the workspace database connections. Connections are grouped by project,in
* ProjectDatabaseManager objects.
*
* @author mkent
* @version 0.3.1
*/
public class DatabaseManager implements IResourceChangeListener
{
private static DatabaseManager instance;
private Map<IProject, ProjectDatabaseManager> projectDatabaseManagerMap;
private Set<IDatabaseListener> listeners = new HashSet<IDatabaseListener>();
/**
* Constructor. Creates and loads the map of databases.
*/
private DatabaseManager()
{
projectDatabaseManagerMap = new HashMap<IProject, ProjectDatabaseManager>();
loadMap();
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
/**
* Loads the database connections for each project in the workspace.
*/
private void loadMap()
{
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (int i = 0; i < projects.length; i++)
{
try
{
if (projects[i].isOpen() && projects[i].exists()
&& projects[i].hasNature(IRailsConstants.RAILS_PROJECT_NATURE))
{
projectDatabaseManagerMap.put(projects[i], new ProjectDatabaseManager(projects[i]));
}
}
catch (CoreException e)
{
DatabaseLog.logError("Rails Project Nature not found", e);
}
}
}
/**
* @return the singleton instance of this class
*/
public static DatabaseManager getInstance()
{
if (instance == null)
{
instance = new DatabaseManager();
}
return instance;
}
/**
* Return the ProjectDatabaseManager for the given project.
*
* @param project
* The project to get the ProjectDatabaseManager for.
* @return The corresponding ProjectDatabaseManager for the project if it exists, or <code>null</code> if none
* exists.
*/
public ProjectDatabaseManager getProjectDatabaseManager(IProject project)
{
return projectDatabaseManagerMap.get(project);
}
/**
* Return all of the ProjectDatabaseManagers.
*
* @return A Collection of all known ProjectDatabaseManagers.
*/
public Collection<ProjectDatabaseManager> getAllProjectDatabaseManagers()
{
return projectDatabaseManagerMap.values();
}
/**
* Add a ProjectDatabaseManager to the map.
*
* @param project
* The project to add a ProjectDatabaseManager for.
*/
public void addProjectDatabaseManager(IProject project)
{
projectDatabaseManagerMap.put(project, new ProjectDatabaseManager(project));
notifyListeners();
}
private void notifyListeners()
{
// TODO Auto-generated method stub
}
/**
* Remove a ProjectDatabaseManager from the map.
*
* @param project
* The project to remove a ProjectDatabaseManager for.
*/
public void removeProjectDatabaseManager(IProject project)
{
projectDatabaseManagerMap.remove(project);
}
/**
* Called when a resource is changed.
*
* @param event
* The event that occurred.
*/
public void resourceChanged(IResourceChangeEvent event)
{
if (event.getType() == IResourceChangeEvent.POST_CHANGE)
{
IResourceDelta[] resources = event.getDelta().getAffectedChildren();
for (int i = 0; i < resources.length; i++)
{
IResource resource = (IResource) resources[i].getResource();
if (resource instanceof IProject)
{
IProject project = (IProject) resource;
// Make sure it's using the correct nature
try
{
switch (resources[i].getKind())
{
case IResourceDelta.ADDED:
if (project.hasNature(IRailsConstants.RAILS_PROJECT_NATURE))
{
addProjectDatabaseManager(project);
for (IDatabaseListener listener : listeners)
{
listener.projectAdded(project);
}
}
break;
case IResourceDelta.CHANGED:
if (project.isOpen() && project.hasNature(IRailsConstants.RAILS_PROJECT_NATURE))
{
addProjectDatabaseManager(project);
for (IDatabaseListener listener : listeners)
{
listener.projectAdded(project);
}
}
break;
case IResourceDelta.REMOVED:
removeProjectDatabaseManager(project);
for (IDatabaseListener listener : listeners)
{
listener.projectRemoved(project);
}
break;
}
}
catch (CoreException e)
{
DatabaseLog.logError("Rails Project Nature not found", e);
e.printStackTrace();
}
}
}
}
}
/**
* Attempt to stop any databases that need stopping.
*/
public void stopAll()
{
try
{
Connection conn = DriverManager.getConnection("jdbc:derby:;shutdown=true");
conn.close();
}
catch (Exception e)
{
// Evidently it _always_ throws an exception
}
}
public void closeAll()
{
// nothing
}
public void addListener(IDatabaseListener listener)
{
listeners.add(listener);
}
public void removeListener(IDatabaseListener listener)
{
listeners.remove(listener);
}
public static Set<String> getEnvironments()
{
Set<String> environments = new HashSet<String>();
Collection<ProjectDatabaseManager> managers = DatabaseManager.getInstance().getAllProjectDatabaseManagers();
for (ProjectDatabaseManager projectDatabaseManager : managers)
{
for (DatabaseDescriptor desc : projectDatabaseManager.getDatabaseDescriptors())
{
environments.add(desc.getName());
}
}
environments.add(IDatabaseConstants.ENV_DEVELOPMENT);
environments.add(IDatabaseConstants.ENV_PRODUCTION);
environments.add(IDatabaseConstants.ENV_TEST);
return environments;
}
void databaseChanged(IProject project)
{
for (IDatabaseListener listener : listeners)
{
listener.databaseSettingsChanged(project);
}
}
} // DatabaseManager