/*
* Copyright 2003-2010 Tufts University Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package tufts.vue;
// $Header: /home/svn/cvs2svn-2.1.1/at-cvs-repo/VUE2/src/tufts/vue/LocalFileDataSource.java,v 1.35 2010-02-03 19:17:40 mike Exp $
import javax.swing.*;
import java.util.Vector;
import java.util.*;
import java.awt.*;
import javax.swing.border.*;
import javax.swing.filechooser.FileSystemView;
import java.io.*;
import osid.filing.*;
import tufts.oki.remoteFiling.*;
import tufts.oki.localFiling.*;
import tufts.oki.shared.*;
import tufts.vue.action.*;
import tufts.Util;
/**
* @version $Revision: 1.35 $ / $Date: 2010-02-03 19:17:40 $ / $Author: mike $
* @author rsaigal
*/
public class LocalFileDataSource extends BrowseDataSource implements Publishable{
private static final org.apache.log4j.Logger Log = org.apache.log4j.Logger.getLogger(LocalFileDataSource.class);
private static final LocalFilingManager LocalFileManager = produceManager();
private static LocalFilingManager produceManager() {
try {
return new LocalFilingManager();
} catch (FilingException t) {
tufts.Util.printStackTrace(t, "new LocalFilingManager");
}
return null;
}
public static LocalFilingManager getLocalFilingManager() {
return LocalFileManager;
}
public LocalFileDataSource() {
}
public LocalFileDataSource(String displayName, String address) throws DataSourceException
{
if (DEBUG.DR) out("NEW: name=" + Util.tags(displayName) + "; address=" + Util.tag(address) + "; " + address);
//if (DEBUG.Enabled) Util.printStackTrace(Util.tags(this) + " NEW: name=" + Util.tags(displayName) + "; address=" + Util.tag(address) + "; " + address);
this.setDisplayName(displayName);
this.setAddress(address);
}
@Override
public String getTypeName() {
return "Local Directory";
}
@Override
protected JComponent buildResourceViewer()
{
if (DEBUG.Enabled) out("buildResourceViewer...");
Vector cabVector = new Vector();
if (getDisplayName().equals("My Computer")) {
// This is a bit of a hack, but we need to do this for
// now because when the resource viewer saves it's state,
// it saves even the defaults (so we can't make this a subclass).
if (DEBUG.Enabled) out("installDesktopFolders...");
installDesktopFolders(cabVector);
if (DEBUG.Enabled) out("installDesktopFolders: " + cabVector);
}
if (this.getAddress().length() > 0) {
osid.shared.Agent agent = null; // This may cause problems later.
LocalCabinet rootNode = LocalCabinet.instance(this.getAddress(),agent,null);
CabinetResource res = CabinetResource.create(rootNode);
cabVector.add(res);
}
VueDragTree fileTree = new VueDragTree(cabVector, this.getDisplayName());
fileTree.setRootVisible(true);
fileTree.setShowsRootHandles(true);
fileTree.expandRow(0);
fileTree.setRootVisible(false);
if (DEBUG.Enabled) out("buildResourceViewer: completed.");
return fileTree;
// if (false) {
// JPanel localPanel = new JPanel();
// JScrollPane rSP = new JScrollPane(fileTree);
// localPanel.setMinimumSize(new Dimension(290,100));
// localPanel.setLayout(new BorderLayout());
// localPanel.add(rSP,BorderLayout.CENTER);
// this.resourceViewer = localPanel;
// } else {
// this.resourceViewer = fileTree;
// }
//DataSourceViewer.refreshDataSourcePanel(this);
}
// @Override
// public synchronized JComponent getResourceViewer()
// {
// if (resourceViewer == null)
// resourceViewer = buildResourceViewer();
// return resourceViewer;
// }
private void installDesktopFolders(Vector cabVector)
{
osid.shared.Agent agent = null; // This may cause problems later.
File home = new File(VUE.getSystemProperty("user.home"));
if (home.exists() && home.canRead()) {
// This might be better handled via addRoot on the LocalFilingManager, but
// we can't set the label (title) for it that way. -- SMF
String[] dirs = { "Desktop", "My Documents", "Documents", "Pictures", "My Documents\\My Pictures", "Photos", "My Documents\\My Photos","Music", "My Documents\\My Music"};
int added = 0;
for (int i = 0; i < dirs.length; i++) {
File dir = new File(home, dirs[i]);
if (dir.exists() && dir.canRead() && dir.isDirectory()) { // TODO: create workaround for Vista bug
// TODO: the above tests ALWAYS RETURN TRUE ON WINDOWS VISTA as of 2008-04-08
// (listing the directory will generate an IO error for you, at least, but that will be a very slow way to do this...)
CabinetResource r = CabinetResource.create(LocalCabinet.instance(dir, agent, null));
// no longer needed: URLResource / CabinetResource will handle for us now
//r.setTitle(dirs[i].substring(dirs[i].lastIndexOf("\\") == -1 ? 0 : dirs[i].lastIndexOf("\\")+1, dirs[i].length()));
cabVector.add(r);
added++;
}
}
if (added == 0 || tufts.Util.isWindowsPlatform() == false) {
CabinetResource r = CabinetResource.create(LocalCabinet.instance(home, agent, null));
String title = "Home";
String user = VUE.getSystemProperty("user.name");
if (user != null)
title += " (" + user + ")";
r.setTitle(title);
cabVector.add(r);
}
}
boolean gotSlash = false;
File volumes = null;
if (tufts.Util.isMacPlatform()) {
volumes = new File("/Volumes");
} else if (tufts.Util.isUnixPlatform()) {
volumes = new File("/mnt");
}
if (volumes != null && volumes.exists() && volumes.canRead()) {
File[] vols = volumes.listFiles();
for (int i = 0; i < vols.length; i++) {
File v = vols[i];
if (!v.canRead() || v.getName().startsWith("."))
continue;
CabinetResource r = CabinetResource.create(LocalCabinet.instance(v, agent, null));
r.setTitle(v.getName());
try {
//r.setTitle(v.getName() + " (" + v.getCanonicalPath() + ")");
if (v.getCanonicalPath().equals("/"))
gotSlash = true;
} catch (Exception e) {
System.err.println(e);
}
cabVector.add(r);
}
}
/*
I mentioned that at home VUE takes over 10 minutes to start up for me.
I've located the problem, its not particularly widespread. The problem
is I have 6-7 tufts network shares that are still connected when I go
home even though I can't actually reach them off of Tufts network. The
timeouts to reach these shares is what slows Vue to a crawl when starting
up. Specifically the call to get the name of the volume like:"xdrive on
'tftmwins1' or 'mkorcy01 on Titan\home-tccs$'. If we're willing to scrap
the volume names on windows and just put drive letters "C:\" , "P:\" I can
get it from about 12 minutes to <10 seconds. The calls to .exists() on
the disconnected drives in LocalFilingManager also sent VUE into a similar
long timeout waiting period.
*/
try {
FileSystemView fsview = null;
if (!tufts.Util.isWindowsPlatform())
fsview = FileSystemView.getFileSystemView();
final LocalFilingManager manager = getLocalFilingManager(); // get a filing manager
LocalCabinetEntryIterator rootCabs = (LocalCabinetEntryIterator) manager.listRoots();
while(rootCabs.hasNext()){
LocalCabinetEntry rootNode = (LocalCabinetEntry)rootCabs.next();
CabinetResource res = CabinetResource.create(rootNode);
if (rootNode instanceof LocalCabinet) {
File f = ((LocalCabinet)rootNode).getFile();
try {
if (f.getCanonicalPath().equals("/") && gotSlash)
continue;
} catch (Exception e) {
System.err.println(e);
}
String sysName = null;
if (!tufts.Util.isWindowsPlatform())
sysName = fsview.getSystemDisplayName(f);
else
sysName = f.toString();
//System.out.println("SysName : " + sysName);
if (sysName != null)
res.setTitle(sysName);
}
cabVector.add(res);
}
// setPublishMode(Publisher.PUBLISH_CMAP);
} catch (Exception ex) {
ex.printStackTrace();
VueUtil.alert(null,ex.getMessage(),VueResources.getString("dialog.settingreserroe.title"));
}
}
public int[] getPublishableModes() {
int modes[] = {Publishable.PUBLISH_MAP,Publishable.PUBLISH_CMAP,Publishable.PUBLISH_ZIP};
return modes;
}
public boolean supportsMode(int mode) {
if(mode == Publishable.PUBLISH_ALL)
return false;
else
return true;
}
public void publish(int mode,LWMap map) throws IOException{
System.out.println("ZIP File: "+map.getFile()+ ","+map+", mode:"+mode);
if(mode == Publishable.PUBLISH_MAP)
publishMap(map);
else if(mode == Publishable.PUBLISH_CMAP)
publishCMap(map);
else if(mode == Publishable.PUBLISH_ALL)
publishAll(map);
else if(mode == Publishable.PUBLISH_ZIP)
publishZip(map);
}
private void publishMap(LWMap map) throws IOException {
File savedMap = PublishUtil.saveMap(map);
InputStream istream = new BufferedInputStream(new FileInputStream(savedMap));
OutputStream ostream = new BufferedOutputStream(new FileOutputStream(ActionUtil.selectFile("ConceptMap","vue")));
int fileLength = (int)savedMap.length();
byte bytes[] = new byte[fileLength];
while (istream.read(bytes,0,fileLength) != -1)
ostream.write(bytes,0,fileLength);
istream.close();
ostream.close();
}
private void publishCMap(LWMap map) throws IOException {
try{
// Note: resourceVector is never initialized in Publisher class. pdw 11-nov-07
File savedCMap = PublishUtil.createIMSCP(Publisher.resourceVector);
InputStream istream = new BufferedInputStream(new FileInputStream(savedCMap));
OutputStream ostream = new BufferedOutputStream(new FileOutputStream(ActionUtil.selectFile("IMSCP","zip")));
int fileLength = (int)savedCMap.length();
byte bytes[] = new byte[fileLength];
while (istream.read(bytes,0,fileLength) != -1)
ostream.write(bytes,0,fileLength);
istream.close();
ostream.close();
} catch(IOException ex){
throw ex;
} catch(Exception ex) {
System.out.println(ex);
VueUtil.alert(VUE.getDialogParent(), VueResources.getString("dialog.export.message")+ex.getMessage(),VueResources.getString("dialog.export.title"),JOptionPane.ERROR_MESSAGE);
}
}
private void publishZip(LWMap map){
try {
if(map.getFile() == null) {
VueUtil.alert(VueResources.getString("dialog.mapsave.message"),VueResources.getString("dialog.mapsave.title"));
return;
}
// Note: resourceVector is never initialized in Publisher class. pdw 11-nov-07
File savedCMap = PublishUtil.createZip(map,Publisher.resourceVector);
InputStream istream = new BufferedInputStream(new FileInputStream(savedCMap));
OutputStream ostream = new BufferedOutputStream(new FileOutputStream(ActionUtil.selectFile("Export to Zip File","zip")));
int fileLength = (int)savedCMap.length();
byte bytes[] = new byte[fileLength];
while (istream.read(bytes,0,fileLength) != -1)
ostream.write(bytes,0,fileLength);
istream.close();
ostream.close();
} catch(Exception ex) {
System.out.println(ex);
VueUtil.alert(VUE.getDialogParent(), VueResources.getString("dialog.export.message")+ex.getMessage(),VueResources.getString("dialog.export.title"),JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
private void publishAll(LWMap map) {
VueUtil.alert(VUE.getDialogParent(), VueResources.getString("dialog.exportall.message"),VueResources.getString("dialog.export.title"),JOptionPane.PLAIN_MESSAGE);
}
private void out(String s) {
Log.debug(String.format("@%x; %s(addr=%s): %s", System.identityHashCode(this), getDisplayName(), getAddress(), s));
}
}