/*
* Copyright (C) 2004 The Concord Consortium, Inc.,
* 10 Concord Crossing, Concord, MA 01742
*
* Web Site: http://www.concord.org
* Email: info@concord.org
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* END LICENSE */
package org.concord.swing;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.TreeSet;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
public class AbstractFileFinder
{
class HTMLDirectoryParser
extends HTMLEditorKit
{
class Callback
extends ParserCallback
{
protected List entries = new Vector();
protected Stack attributeStack = new Stack();
public Callback()
{
}
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos)
{
super.handleStartTag(t, a, pos);
if (t == HTML.Tag.A)
{
String href = (String) a.getAttribute(HTML.Attribute.HREF);
entries.add(href);
}
}
public void handleEndTag(HTML.Tag t, int pos)
{
}
public void clearEntries()
{
entries.clear();
}
public List getEntries()
{
return entries;
}
}
protected URL base;
protected Parser parser;
protected Callback callback;
public HTMLDirectoryParser(URL url)
{
base = url;
parser = getParser();
callback = new Callback();
}
protected Reader getURLReader(String dir)
{
URL url;
Reader reader = null;
try
{
url = new URL(abstractDirectory, dir);
reader = new InputStreamReader(url.openStream());
}
catch (MalformedURLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return reader;
}
public void parse(String dirName)
{
try
{
callback.clearEntries();
parser.parse(getURLReader(dirName), callback, false);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public List getEntries()
{
return callback.getEntries();
}
}
protected URL abstractDirectory;
protected HTMLDirectoryParser htmlDirectoryParser;
protected Map directoryMap;
protected TreeSet directorySet;
public AbstractFileFinder()
{
}
public URL getAbstractDirectory()
{
return abstractDirectory;
}
protected void addDirectorySetEntry(String entryName, URL url)
{
File entryFile = new File(entryName);
String parentPath = entryFile.getParent();
parentPath = (parentPath == null) ? "" : parentPath + "/";
parentPath = parentPath.replace(File.separatorChar, '/');
String key = "jar:" + url.getFile() + parentPath;
TreeSet set = findDirectorySet(key, url);
set.add(entryFile);
File file = new File(parentPath);
entryName = file.getParent();
if (entryName != null)
addDirectorySetEntry(entryName + "/", url);
}
protected TreeSet findDirectorySet(String key, URL url)
{
TreeSet set = (TreeSet) directoryMap.get(key);
if (set == null)
{
set = new TreeSet();
directoryMap.put(key, set);
}
return set;
}
protected TreeSet initializeDirectorySet(URL url)
{
TreeSet set = (TreeSet) directoryMap.get(url.toString());
if (set == null)
{
try
{
JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarConnection.getJarFile();
Enumeration jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements())
{
JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
String entryName = jarEntry.getName();
addDirectorySetEntry(entryName, url);
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
set = (TreeSet) directoryMap.get(url.toString());
}
return set;
}
public void setAbstractDirectory(URL url)
{
abstractDirectory = url;
if (abstractDirectory.getProtocol().toLowerCase().equals("http"))
{
htmlDirectoryParser = new HTMLDirectoryParser(abstractDirectory);
}
if (abstractDirectory.getProtocol().toLowerCase().equals("jar"))
{
directorySet = initializeDirectorySet(abstractDirectory);
}
}
public void setDirectoryMap(Map map)
{
directoryMap = map;
}
public void collectEntries(String dirName, List entries)
{
if (abstractDirectory.getProtocol().toLowerCase().equals("http"))
collectWebEntries(dirName, entries);
if (abstractDirectory.getProtocol().toLowerCase().equals("jar"))
collectJarEntries(dirName, entries);
}
public void collectJarEntries(String dirName, List entries)
{
String key = "jar:" + abstractDirectory.getFile() + dirName;
directorySet = (TreeSet) directoryMap.get(key);
Iterator directoryEntries = directorySet.iterator();
while (directoryEntries.hasNext())
{
File entryFile = (File) directoryEntries.next();
String entryName = entryFile.getName();
if (directoryMap.get(key + entryName + "/") != null)
entryName += "/";
entries.add(entryName);
}
}
public void collectWebEntries(String dirName, List entries)
{
htmlDirectoryParser.parse(dirName);
List tagList = htmlDirectoryParser.getEntries();
for (int i = 0; i < tagList.size(); i++)
{
String href = (String) tagList.get(i);
if (href.startsWith("/"))
continue;
if (href.startsWith("?"))
continue;
URI uri;
try
{
uri = new URI(href);
if (uri.isAbsolute())
continue;
}
catch (URISyntaxException e)
{
continue;
}
entries.add(href);
}
}
}