/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.editors.helpers;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
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.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import de.innovationgate.eclipse.editors.Plugin;
import de.innovationgate.eclipse.utils.wga.WGADesignStructureHelper;
public class ResourceIndexManager implements IResourceChangeListener {
private Connection _conn;
private static String DBNAME = "fileReferences";
public ResourceIndexManager(File base) throws SQLException, ClassNotFoundException {
Class.forName("org.hsqldb.jdbcDriver");
if (Plugin.getDefault().isDebugging()) {
_conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/resourceIndexManager", "sa", "");
} else {
_conn = DriverManager.getConnection("jdbc:hsqldb:" + new File(base, DBNAME).getAbsolutePath(), "sa", "");
}
}
public void init() throws CoreException {
try {
Statement st = _conn.createStatement();
st.executeUpdate("CREATE TABLE references (FileType char(25), Medium char(250),Path varchar(1000), File char(250), Project char(250))");
insertFiles(ResourcesPlugin.getWorkspace().getRoot(), "");
st.close();
} catch (SQLException e) {
}
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
private void insertFiles(IContainer container, String path) throws SQLException, CoreException {
if (path.equals("") || path.equals("/")) {
path = container.getFullPath().toString();
} else {
path = path + "/" + container.getName();
}
IResource[] currentIResources;
if(container.isAccessible()){
currentIResources = container.members();
for (int i = 0; i < currentIResources.length; i++) {
if (currentIResources[i] instanceof IContainer) {
IContainer current = (IContainer) currentIResources[i];
insertFiles(current, path);
}
if (currentIResources[i] instanceof IFile) {
IFile ifile = (IFile) currentIResources[i];
addIntoDB(ifile);
}
}
}
}
private void addIntoDB(IFile ifile) throws SQLException {
updateFileRefs("INSERT INTO references(FileType,Medium,Path,File,Project) VALUES(?,?,?,?,?)", ifile);
}
private void removeFromDB(IFile ifile) throws SQLException {
updateFileRefs("DELETE FROM references WHERE FileType = ? AND Medium = ? AND Path = ? AND File = ? AND Project = ?", ifile);
}
private void updateFileRefs(String expression, IFile ifile) throws SQLException {
String file = ifile.getName();
String filetype = ifile.getFileExtension();
String project = ifile.getProject().getName();
String insertpath = ifile.getParent().getProjectRelativePath().toString();
String medium = WGADesignStructureHelper.determineMediaKey(ifile);
//insertpath = insertpath.substring(0, insertpath.indexOf(ifile.getName()));
PreparedStatement st = _conn.prepareStatement(expression);
st.setString(1, filetype);
st.setString(2, medium);
st.setString(3, insertpath);
st.setString(4, file);
st.setString(5, project);
st.executeUpdate();
st.close();
}
public void close() throws SQLException {
Statement st = _conn.createStatement();
st.execute("SHUTDOWN");
_conn.close();
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
}
public Set<String> getTMLpaths(IFile file, String medium) {
Set<String> resources = new HashSet<String>();
IContainer design = new WGADesignStructureHelper(file).getDesignRoot();
if (design != null) {
String expression = "SELECT * FROM references WHERE Project = ? AND FileType = ? AND Medium = ? AND Path Like ?";
PreparedStatement st = null;
ResultSet rs = null;
try {
st = _conn.prepareStatement(expression);
st.setString(1, file.getProject().getName());
st.setString(2, "tml");
st.setString(3, medium);
st.setString(4, design.getProjectRelativePath() + "/tml/%");
rs = st.executeQuery();
while (rs.next()) {
String resource = rs.getString("Path");
if (!resource.endsWith("/")) {
resource += "/";
}
resource += rs.getString("File");
resources.add(resource);
}
} catch (SQLException e) {
Plugin.getDefault().logError("Unable to lookup tml paths for project '" + file.getProject().getName() + "' and designRoot '" + design.getLocation().toString() + "'.", e);
} finally {
cleanupSQLResources(st, rs);
}
}
return resources;
}
public void resourceChanged(IResourceChangeEvent event) {
if (event.getType() != IResourceChangeEvent.POST_CHANGE)
return;
IResourceDelta rootDelta = event.getDelta();
IResourceDelta docDelta = rootDelta.findMember(new Path(""));
if (docDelta == null)
return;
final ArrayList<IResource> removed = new ArrayList<IResource>();
IResourceDeltaVisitor rvisitor = new IResourceDeltaVisitor() {
public boolean visit(IResourceDelta delta) {
if (delta.getKind() != IResourceDelta.REMOVED)
return true;
IResource resource = delta.getResource();
if (resource.getType() == IResource.FILE) {
removed.add(resource);
}
return true;
}
};
final ArrayList<IResource> added = new ArrayList<IResource>();
IResourceDeltaVisitor avisitor = new IResourceDeltaVisitor() {
public boolean visit(IResourceDelta delta) {
if (delta.getKind() != IResourceDelta.ADDED)
return true;
IResource resource = delta.getResource();
if (resource.getType() == IResource.FILE) {
added.add(resource);
}
return true;
}
};
try {
docDelta.accept(rvisitor);
docDelta.accept(avisitor);
} catch (CoreException e) {
}
if (removed.size() == 0 && added.size() == 0)
return;
Iterator<IResource> rit = removed.iterator();
Iterator<IResource> ait = added.iterator();
while (rit.hasNext()) {
try {
removeFromDB((IFile) rit.next());
} catch (SQLException e) {
Plugin.getDefault().logError("Can't remove file from db", e);
}
}
while (ait.hasNext()) {
try {
addIntoDB((IFile) ait.next());
} catch (SQLException e) {
Plugin.getDefault().logError("Can't add new file to db", e);
}
}
}
public Set<String> getMediumKeys(IFile file) {
IProject project = file.getProject();
Set<String> resources = new HashSet<String>();
IContainer design = new WGADesignStructureHelper(file).getDesignRoot();
String expression = "SELECT distinct Medium FROM references WHERE Project = ? AND Path Like ?";
PreparedStatement st = null;
ResultSet rs = null;
try {
st = _conn.prepareStatement(expression);
st.setString(1, project.getName());
st.setString(2, "designs/" + design.getName() + "/tml/%");
rs = st.executeQuery();
while (rs.next()) {
if (!rs.getString("Medium").equals("") && !rs.getString("Medium").startsWith(".")) {
resources.add(rs.getString("Medium"));
}
}
} catch (SQLException e) {
Plugin.getDefault().logError("Unable to lookup medium keys for project '" + project.getName() + "' and designRoot '" + design.getLocation().toString() + "'.", e);
} finally {
cleanupSQLResources(st, rs);
}
return resources;
}
public Set<String> getScriptPaths(IContainer designRoot, String scriptType) {
Set<String> resources = new HashSet<String>();
IProject project = designRoot.getProject();
PreparedStatement st = null;
ResultSet rs = null;
try {
String expression = "SELECT Path, File FROM references WHERE Project = ? AND FileType = ? AND Path Like ?";
st = _conn.prepareStatement(expression);
st.setString(1, project.getName());
st.setString(2, scriptType);
designRoot.getProjectRelativePath().append("scripts").append(scriptType);
st.setString(3, designRoot.getProjectRelativePath().append("scripts").append(scriptType).toString() + "%");
rs = st.executeQuery();
while (rs.next()) {
String resource = rs.getString("Path");
if (!resource.endsWith("/")) {
resource += "/";
}
resource += rs.getString("File");
resources.add(resource);
}
} catch (SQLException e) {
Plugin.getDefault().logError("Unable to lookup script paths for project '" + project.getName() + "' and designRoot '" + designRoot.getLocation().toString() + "'.", e);
} finally {
cleanupSQLResources(st, rs);
}
return resources;
}
private void cleanupSQLResources(Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
}
}
}
}