/*
* 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.
*/
/*
* OpenAction.java
*
* Created on April 2, 2003, 12:40 PM
*/
package tufts.vue.action;
/**
*
* @author akumar03
*/
import java.io.*;
import java.util.zip.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import tufts.vue.*;
import tufts.Util;
public class OpenAction extends VueAction
{
private static final org.apache.log4j.Logger Log = org.apache.log4j.Logger.getLogger(OpenAction.class);
//public static final String ZIP_IMPORT_LABEL ="Imported";
public OpenAction(String label) {
super(label, null, ":general/Open");
}
public OpenAction() {
this("Open");
}
// workaround for rapid-succession Ctrl-O's which pop multiple open dialogs
private static final Object LOCK = new Object();
private static boolean openUnderway = false;
public void actionPerformed(ActionEvent e) {
synchronized (LOCK) {
if (openUnderway)
return;
openUnderway = true;
}
try {
File[] file = ActionUtil.openMultipleFiles("Open Map", VueFileFilter.VUE_DESCRIPTION);
if (file == null)
return;
for (int i=0;i<file.length;i++)
displayMap(file[i]);
Log.info(e.getActionCommand() + ": completed.");
} finally {
openUnderway = false;
}
}
public static void reloadMap(LWMap map)
{
displayMap(map.getFile());
}
public static void displayMap(File file) {
VUE.displayMap(file);
/*
if (file != null) {
RecentlyOpenedFilesManager rofm = RecentlyOpenedFilesManager.getInstance();
rofm.updateRecentlyOpenedFiles(file.getAbsolutePath());
VUE.activateWaitCursor();
try {
LWMap loadedMap = loadMap(file.getAbsolutePath());
VUE.displayMap(loadedMap);
} finally {
VUE.clearWaitCursor();
VUE.getPathwayPanel().updateEnabledStates();
}
}
*/
}
// public static boolean isVueIMSCPArchive(File file) {
// if (!file.getName().toLowerCase().endsWith(".zip"))
// return false;
// try {
// ZipFile zipFile = new ZipFile(file);
// return zipFile.getEntry(IMSCP.MAP_FILE) != null && zipFile.getEntry(IMSCP.MANIFEST_FILE) != null;
// } catch (Throwable t) {
// Log.warn(t);
// return false;
// }
// }
// public static boolean isVueArchive(File file) {
// return file.getName().toLowerCase().endsWith(VueUtil.VueArchiveExtension);
// }
public static LWMap loadMap(java.net.URL url) {
try {
if (DEBUG.CASTOR) Log.debug("Unmarshalling from " + url);
LWMap map = ActionUtil.unmarshallMap(url);
return map;
} catch (Exception e) {
Log.error("loadMap " + tufts.Util.tags(url), e);
VueUtil.alert(null, VueResources.getString("openaction.mapopen.error"),VueResources.getString("openaction.mapopen.title"));
//tufts.Util.printStackTrace(e);
return null;
}
}
// todo: have only one root loadMap that hanldes files & urls -- actually, make it ALL url's
// TODO: this should be re-named openFile or openVueContent (as it handles all sorts of "vue" files)
// (and also, again, merge this with ActionUtil unmarshall code?)
public static LWMap loadMap(String filename) {
LWMap map = null;
try {
map = doLoadMap(filename);
} catch (FileNotFoundException e) {
// maybe move all exception code here, taking the file-not-found handling
Log.error("loadMap " + Util.tags(filename), e);
VueUtil.alert(null, "\"" + filename + "\"" +VueResources.getString("openaction.mapnotfound.error"), VueResources.getString("openaction.mapnotfound.title"));
map = LWMap.create(filename);
} catch (Throwable t) {
// out of the Open File dialog box.
Log.error("loadMap " + Util.tags(filename), t);
if (t.getCause() != null)
t = t.getCause();
final String message;
final String exception;
if (t instanceof EmptyFileException) {
message = "There is no data in file \"%s\"\n\n%s";
exception = t.getMessage();
// special case: create a new map with the empty file name
map = LWMap.create(filename);
} else {
// if we still want the "version" part of this warning, it needs to be
// delivered from below when we actually detect a VUE data-versioning problem:
// this message is inappropriate for generic exceptions
//message = "\"%s\" cannot be opened in this version of VUE.\n\nProblem:\n%s";
message = "\"%s\" cannot be opened in VUE.\n\nProblem:\n%s";
exception = t.toString();
}
VueUtil.alert(String.format(message, filename, Util.formatLines(exception, 80)),
VueResources.getString("openaction.openmapproblem.title"));
//tufts.Util.printStackTrace(t);
}
return map;
}
private static LWMap doLoadMap(String filename)
throws java.io.FileNotFoundException,
java.util.zip.ZipException,
java.io.IOException
{
if (DEBUG.CASTOR || DEBUG.IO) Log.debug("doLoadMap: name=" + filename);
File file = new File(filename);
//int dotIndex = file.getName().lastIndexOf('.');
//String extension = "";
//if (dotIndex >= 0 && file.getName().length() > 1)
// extension = file.getName().substring(dotIndex + 1).toLowerCase();
//System.out.println("Extension = "+extension);
// TODO: the current method of saving VUE zip archives doesn't preserve the
// original resource reference. We could easily do this by changing this to
// a system where the original resources are left alone, (and the archiving
// process can speedily pull the images from the disk image cache), and
// here, when restoring, simply pre-load the disk cache with images included
// in the archive. Unless we want to provide other functionaly, such as the
// ability for the user to get at the content directly in a special folder,
// look at/edit it, etc.
// Also problem: opening a VUE .zip archive, then trying to save it normally
// won't produce something restorable. Don't know if saving it as
// a zip archive again will work or not.
// TODO PREF: may want option for user to by default use the cached on-disk
// image version of something when double clicking, v.s., going back out
// online for the original resource. (Would be nice also to do this by
// default if not online!) E.g., opening an image from the cache on MacOSX
// would immediately open in, usually in Preview, instead of reloading it in
// Safari.
LWMap map = null;
if (Archive.isVuePackage(file)) {
map = Archive.openVuePackage(file);
} else if (Archive.isVueIMSCPArchive(file)) {
map = Archive.loadVueIMSCPArchive(file);
} else {
map = ActionUtil.unmarshallMap(file);
}
return map;
}
// private static LWMap unpackVueArchive(File file)
// throws java.io.IOException,
// java.util.zip.ZipException
// {
// Log.info("Unpacking VUE zip archive: " + file);
// final ZipFile zipFile = new ZipFile(file);
// //Vector<Resource> resourceVector = new Vector();
// //File resourceFolder = new File(VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+IMSCP.RESOURCE_FILES);
// //if(resourceFolder.exists() || resourceFolder.mkdir()) {
// final ZipInputStream zin = new ZipInputStream(new FileInputStream(file));
// ZipEntry entry;
// ZipEntry mapEntry = null;
// String mapFile = null;
// final String unpackingDir = VUE.getSystemProperty("java.io.tmpdir"); // or, could use same dir a current package file is at
// while ( (entry = zin.getNextEntry()) != null ) {
// String location = unzip(zin, entry, unpackingDir);
// final String comment = SaveAction.getComment(entry);
// if (comment != null && comment.startsWith(SaveAction.MapArchiveKey)) {
// mapEntry = entry;
// mapFile = location;
// Log.debug("Found map in archive: " + entry + "; at " + location);
// }
// //unzip(zin, entry, null);
// // //if (DEBUG.IO) System.out.println("ZipEntry: " + e.getName());
// // if(!e.getName().equalsIgnoreCase(IMSCP.MAP_FILE) && !e.getName().equalsIgnoreCase(IMSCP.MANIFEST_FILE)){
// // // todo: may want to add a Resource.Factory.get(ZipEntry) method
// // Resource resource = Resource.getFactory().get(e.getName());
// // resourceVector.add(resource);
// // //if (DEBUG.IO) System.out.println("Resource: " + resource);
// // }
// }
// zin.close();
// // File mapFile = new File(VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+IMSCP.MAP_FILE);
// // LWMap map = ActionUtil.unmarshallMap(mapFile);
// // map.setFile(null);
// // map.setLabel(ZIP_IMPORT_LABEL);
// // for (Resource r : resourceVector) {
// // replaceResource(map, r,
// // Resource.getFactory().get(VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+r.getSpec()));
// // //new URLResource(VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+r.getSpec()));
// // }
// // map.markAsSaved();
// return ActionUtil.unmarshallMap(new File(mapFile));
// //return null;
// }
// /**
// * @param location -- if null, entry will be unzipped in local (current) working directory,
// * otherwise, entry will be unzipped at the given path location in the file system.
// * @return filename of unzipped file
// */
// public static String unzip(ZipInputStream zin, ZipEntry entry, String location)
// throws IOException
// {
// final String filename;
// if (location == null)
// filename = entry.getName();
// else
// filename = location + File.separator + entry.getName();
// if (DEBUG.IO) {
// // Note: entry.getSize() is not known until the entry is unpacked
// final String comment = SaveAction.getComment(entry);
// String msg = "Unzipping to " + filename + " from entry " + entry;
// if (comment != null)
// msg += "\n\t[" + comment + "]";
// Log.debug(msg);
// }
// final File newFile = createFile(filename);
// Log.info("Unpacking " + newFile);
// final FileOutputStream out = new FileOutputStream(newFile);
// byte [] b = new byte[1024];
// int len = 0;
// int wrote = 0;
// while ( (len=zin.read(b))!= -1 ) {
// wrote += len;
// out.write(b,0,len);
// }
// out.close();
// if (DEBUG.IO) {
// Log.debug(" Unzipped " + filename + "; wrote=" + wrote + "; size=" + entry.getSize());
// }
// return filename;
// }
// public static File createFile(String name)
// throws IOException
// {
// final File file = new File(name);
// File parent = file;
// while ( (parent = parent.getParentFile()) != null) {
// //Log.debug("Parent: " + parent);
// if (parent.getPath().equals("/")) {
// //Log.debug("skipping " + parent);
// break;
// }
// if (!parent.exists()) {
// Log.debug("Creating: " + parent);
// parent.mkdir();
// }
// }
// file.createNewFile();
// return file;
// }
// private static void unzipIMSCP(ZipInputStream zin, ZipEntry entry)
// throws IOException
// {
// unzip(zin, entry, VueUtil.getDefaultUserFolder().getAbsolutePath());
// // String fname = VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+s;
// // if (DEBUG.IO) System.out.println("unzipping " + s + " to " + fname);
// // FileOutputStream out = new FileOutputStream(fname);
// // byte [] b = new byte[512];
// // int len = 0;
// // while ( (len=zin.read(b))!= -1 ) {
// // out.write(b,0,len);
// // }
// // out.close();
// }
// private static LWMap loadVueIMSCPArchive(File file)
// throws java.io.FileNotFoundException,
// java.util.zip.ZipException,
// java.io.IOException
// {
// Log.info("Unpacking VUE IMSCP zip archive: " + file);
// ZipFile zipFile = new ZipFile(file);
// Vector<Resource> resourceVector = new Vector();
// File resourceFolder = new File(VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+IMSCP.RESOURCE_FILES);
// if(resourceFolder.exists() || resourceFolder.mkdir()) {
// ZipInputStream zin = new ZipInputStream(new FileInputStream(file));
// ZipEntry e;
// while ((e=zin.getNextEntry()) != null) {
// unzipIMSCP(zin, e);
// //if (DEBUG.IO) System.out.println("ZipEntry: " + e.getName());
// if(!e.getName().equalsIgnoreCase(IMSCP.MAP_FILE) && !e.getName().equalsIgnoreCase(IMSCP.MANIFEST_FILE)){
// // todo: may want to add a Resource.Factory.get(ZipEntry) method
// Resource resource = Resource.getFactory().get(e.getName());
// resourceVector.add(resource);
// //if (DEBUG.IO) System.out.println("Resource: " + resource);
// }
// }
// zin.close();
// }
// File mapFile = new File(VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+IMSCP.MAP_FILE);
// LWMap map = ActionUtil.unmarshallMap(mapFile);
// map.setFile(null);
// map.setLabel(ZIP_IMPORT_LABEL);
// for (Resource r : resourceVector) {
// replaceResource(map, r,
// Resource.getFactory().get(VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+r.getSpec()));
// //new URLResource(VueUtil.getDefaultUserFolder().getAbsolutePath()+File.separator+r.getSpec()));
// }
// map.markAsSaved();
// return map;
// }
// public static void replaceResource(LWMap map,Resource r1,Resource r2) {
// Iterator i = map.getAllDescendentsIterator();
// while(i.hasNext()) {
// LWComponent component = (LWComponent) i.next();
// if(component.hasResource()){
// Resource resource = component.getResource();
// if(resource.getSpec().equals(r1.getSpec()))
// component.setResource(r2);
// }
// }
// }
/** test harness for opening a whole bunch of map files just to make sure we can parse and create an LWMap model from them */
public static void main(String args[]) throws Exception {
//VUE.parseArgs(args);
VUE.debugInit(false);
VUE.init(args);
//VUE.initApplication();
//new TextBox(null, "DEBUG-TEXTBOX");
SaveAction.PACKAGE_DEBUG = true;
DEBUG.IO = true;
LWMap map = null;
for (String arg : args) {
map = null;
if (arg.charAt(0) == '-')
continue;
System.err.println("Attempting to read map from " + arg);
Throwable tx = null;
try {
if (arg.indexOf(':') >= 0)
map = OpenAction.loadMap(new java.net.URL(arg));
else
map = OpenAction.doLoadMap(arg);
} catch (OutOfMemoryError e) {
System.err.println("@@@OUT OF MEMORY " + e);
System.exit(-1);
} catch (Throwable t) {
t.printStackTrace();
tx = t;
}
final Object result;
if (map == null && tx != null) {
if (tx.getCause() != null)
result = tx.getCause();
else
result = tx;
} else
result = map;
// If exception has multi-line content, and we're grepping output for '@@@',
// we're ensure to include this token after the exception is printed, so
// we can still see the file that failed.
//Log.error(String.format("@@@Free: %4.1fm; Loaded: %-60s from @@@ %s\n",
System.err.format("@@@Free: %5.1fm; Loaded: %-60s from @@@ [%s]\n",
(float) (Runtime.getRuntime().freeMemory() / (float) (1024*1024)),
result, arg);
//System.err.println("@@@ARG[" + arg + "]");
//System.out.println("@@@Loaded map: " + map + " from " + arg);
}
System.out.println("@@@Done.");
// if (map != null) {
// //SaveAction.writeArchive(map, new File("test.var"));
// //createVUEArchive(map, new File("test.var"));
// }
// String file = args.length == 0 ? "test.xml" : args[0];
// System.err.println("Attempting to read map from " + file);
// DEBUG.Enabled = true;
// LWMap map;
// if (file.indexOf(':') >= 0)
// map = OpenAction.loadMap(new java.net.URL(file));
// else
// map = OpenAction.loadMap(file);
// System.out.println("Loaded map: " + map);
}
}