/* * 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; import java.awt.*; import java.applet.*; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Properties; import javax.swing.*; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.common.collect.Multiset; import com.jgoodies.looks.LookUtils; import com.jgoodies.looks.plastic.Plastic3DLookAndFeel; import com.sun.org.apache.xerces.internal.impl.XMLScanner; import edu.tufts.vue.mbs.AnalyzerResult; import tufts.vue.ds.DataAction; import tufts.vue.ds.DataTree; import tufts.vue.ds.Schema; import tufts.vue.ds.XMLIngest; import tufts.vue.ds.XmlDataSource; import tufts.vue.gui.GUI; import tufts.vue.gui.VueMenuBar; // To get to run from classpath: had to be sure to create a symlink to // VueResources.properties // from the build/classes tree to the source tree. // Of course, now need all the damn support libraries... /** * Experimental VUE applet. * * @version $Revision: 1.25 $ / $Date: 2010-02-03 19:17:40 $ / $Author: mike $ */ public class VueApplet extends JApplet { private static boolean isInited = false; private static boolean firstInit = true; private static MapViewer viewer = null; private static JPanel toolbarPanel = null; private static JComponent toolbar = null; private static boolean fullyStopped = false; private static boolean isZotero = false; // If want to have viewer left in same state when go forwrd/back in browser, // will need javacript assist to associate the viewer with the instance of a // web browser page: // new applet & context objects are created even when you go forward/back // pages. private static MapTabbedPane mMapTabbedPane = null; // applet parameters /* * Valid values for zoteroPlugin : true , false default value: false */ private static final String zoteroPlugin = "zoteroPlugin"; private static JApplet instance; public VueApplet() { instance = this; this.getRootPane().setDoubleBuffered(true); // VUE.setAppletContext(this.getAppletContext()); } public void init() { super.init(); this.setBackground(new Color(225,225,225)); try { UIManager.put("ClassLoader", LookUtils.class.getClassLoader()); UIManager.setLookAndFeel(new Plastic3DLookAndFeel()); } catch (Exception e) { System.out.println("Couldn't load jlooks look and feel"); } //I think the redone content window makes this code moot. /* GUI.invokeAfterAWT(new Runnable() { public void run() { if (VUE.getDRBrowser() != null) VUE.getDRBrowser().loadDataSourceViewer(); // Kick-off tufts.vue.VueDataSource viewer build threads: // must be done in AWT to be threadsafe, as involves // non-synhcronized code in tufts.vue.VueDataSource while // setting up the threads // DataSourceViewer.cacheDataSourceViewers(); }}); */ } public static String getActiveMapPath() { return VUE.getActiveMap().getFile().getAbsolutePath(); } public static String getActiveMapDisplayTitle() { return VUE.getActiveMap().getDisplayLabel(); } public static JApplet getInstance() { return instance; } public void start() { super.start(); instance = this; VUE.setAppletContext(this.getAppletContext()); if (!firstInit) while(!fullyStopped) { try { Thread.sleep(3000); System.out.println("WAIT"); } catch (InterruptedException e) { //keep trying } } fullyStopped = false; super.init(); processAppletParameters(); getContentPane().setLayout(new BorderLayout()); msg("init\n\tapplet=" + Integer.toHexString(hashCode()) + "\n\tcontext=" + getAppletContext()); VUE.initUI(); VUE.initApplication(); loadViewer(); if (!VUE.getLeftTabbedPane().isEnabled()) VUE.getLeftTabbedPane().setEnabled(true); //------------------------------------------------------- // Trigger the load of the OSID's and set up UrlAuthentication //------------------------------------------------------- VUE.initDataSources(); GUI.invokeAfterAWT(new Runnable() { public void run() { final DRBrowser DR_BROWSER = VUE.getDRBrowser(); if (DR_BROWSER != null) DR_BROWSER.loadDataSourceViewer(); // Kick-off tufts.vue.VueDataSource viewer build threads: // must be done in AWT to be threadsafe, as involves // non-synhcronized code in tufts.vue.VueDataSource while // setting up the threads // DataSourceViewer.cacheDataSourceViewers(); // addZoteroDatasource("collectionName", "/Users/mkorcy01/Desktop/6.xml"); }}); isInited=true; } public void ToggleAllVisible() { SwingUtilities.invokeLater(new Runnable() {public void run() { tufts.vue.gui.DockWindow.ToggleAllVisible(); }}); } public boolean AllWindowsHidden() { return tufts.vue.gui.DockWindow.AllWindowsHidden(); } public void ShowPreviouslyHiddenWindows() { SwingUtilities.invokeLater(new Runnable() {public void run() { tufts.vue.gui.DockWindow.ShowPreviouslyHiddenWindows(); }}); } public void HideAllDockWindows() { SwingUtilities.invokeLater(new Runnable() {public void run() { tufts.vue.gui.DockWindow.HideAllWindows(); }}); } public void stop() { super.stop(); // // System.gc(); } public void destroy() { SwingUtilities.invokeLater(new Runnable() { public void run() { tufts.vue.gui.DockWindow.HideAllWindows(); EditorManager.destroy(); VueToolbarController.destroyController(); VUE.getActiveViewer().destroyContextMenus(); }}); // VUE.finalizeDocks(); fullyStopped = true; isInited=false; msg("stop"); //msg("destroy"); } public static boolean isInited() { return isInited; } public static boolean isZoteroApplet() { return isZotero; } private final void processAppletParameters() { String zoteroPlugin = this.getParameter(this.zoteroPlugin); if (zoteroPlugin != null) zoteroPlugin = zoteroPlugin.toLowerCase(); if (zoteroPlugin != null && zoteroPlugin.equals("true")) { isZotero=true; // tufts.vue.action.TextOpenAction.setZoteroPrototypeEnabled(true); } } public static String getActiveMapItems() { LWMap active = VUE.getActiveMap(); java.util.Iterator it = active.getAllDescendents(LWComponent.ChildKind.PROPER).iterator(); String items = ""; do { if(!it.hasNext()) break; LWComponent n = (LWComponent)it.next(); if(n instanceof LWNode) { items = (new StringBuilder()).append(items).append(n.getLabel()).append(",").toString(); String id = null; try { id = n.getResource().getProperty("Zotero.id"); } catch(Exception e) { System.out.println("Exception in zotero import from vue: no zotero id"); } if(id == null) items = (new StringBuilder()).append(items).append("none,").toString(); else items = (new StringBuilder()).append(items).append(id).append(",").toString(); String url = null; try { url = n.getResource().getSpec(); } catch(Exception e) { System.out.println("Exception in zotero import from vue: no zotero url"); } if(url == null) items = (new StringBuilder()).append(items).append("none").toString(); else items = (new StringBuilder()).append(items).append(url).toString(); items = (new StringBuilder()).append(items).append("\n").toString(); } } while(true); return items; } public synchronized void loadViewer() { msg("got viewer"); msg("is applet ? " + VUE.isApplet()); msg("setting menu bar..."); VueMenuBar vmb = new VueMenuBar(); vmb.setBorderPainted(false); setJMenuBar(vmb); final VueToolbarController tbc = VueToolbarController.getController(); toolbar = tbc.getToolbar().getMainToolbar(); toolbarPanel = VUE.constructToolPanel(toolbar); getContentPane().setBackground(toolbarPanel.getBackground()); getContentPane().add(toolbarPanel, BorderLayout.NORTH); getContentPane().add(VUE.getLeftTabbedPane(),BorderLayout.CENTER); validate(); VUE.displayMap(new LWMap("New Map")); msg("validating..."); msg("loading complete"); // VUE.getSelection().clearAndNotify(); //VUE.setActive(MapViewer.class, this, null); // no open viewers firstInit=false; } public void setSize(int width, int height) { super.setSize(width, height); this.getContentPane().setSize(width, height); Container c = this.getParent(); while (c !=null) { c.setSize(width, height); c.validate(); c = c.getParent(); } // this.invalidate(); // this.getContentPane().validate(); // this.validate(); //this.repaint(); } private void msg(String s) { System.out.println("VueApplet: " + s); } @SuppressWarnings("unchecked") public static void displayZoteroExport(final String urlString) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { File tempFile = null; tempFile = File.createTempFile(new Long(System .currentTimeMillis()).toString(), null); InputStream io = null; io = getInputStream(urlString); byte[] buf = new byte[256]; int read = 0; java.io.FileOutputStream fos = null; fos = new java.io.FileOutputStream(tempFile); while ((read = io.read(buf)) > 0) { fos.write(buf, 0, read); } tufts.vue.action.TextOpenAction.displayMap(tempFile); } catch (Exception e) { e.printStackTrace(); } return null; } }); } public static boolean isGuiInited() { return GUI.isGUIInited(); } public static String getActiveResourceSpec() { LWSelection selection = VUE.getActiveViewer().getSelection(); if (!selection.isEmpty()) { return selection.get(0).getResource().getSpec(); } else return null; } @SuppressWarnings("unchecked") public static void addLinksToMap(final String content) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // Reader reader = openReader(); javax.xml.parsers.DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(true); factory.setIgnoringComments(true); //factory.setCoalescing(true); factory.setValidating(false); // We don't use is.setEncoding(), as openReader will already have handled that // is.setCharacterStream(reader); InputStream is; try { is = new java.io.ByteArrayInputStream(content.getBytes("UTF-8")); final org.w3c.dom.Document doc = factory.newDocumentBuilder().parse((InputStream) is); NodeList nodeLst = doc.getElementsByTagName("link"); //build multimap of links Multimap<String,String> map = Multimaps.newArrayListMultimap(); for (int s = 0; s < nodeLst.getLength(); s++) { Node fstNode = nodeLst.item(s); if (fstNode.getNodeType() == Node.ELEMENT_NODE) { NamedNodeMap atts = fstNode.getAttributes(); Node n = atts.item(0); Node val = atts.item(1); map.put(n.getNodeValue(), val.getNodeValue()); } } java.util.Collection<LWComponent> comps = VUE.getActiveMap().getAllDescendents(); java.util.Iterator<LWComponent> iter = comps.iterator(); //build map of data row nodes HashMap<String,LWNode> dataRowNodes = new HashMap<String,LWNode>(); while (iter.hasNext()) { LWComponent comp = iter.next(); if (comp.isDataRowNode()) { String fromId= comp.getDataValue("id"); dataRowNodes.put(fromId, (LWNode)comp); } } //draw links Multiset<String> keys = map.keys(); java.util.Iterator<String> linkIterator = keys.iterator(); while (linkIterator.hasNext()) { String fromId = linkIterator.next(); Collection<String> toIds = map.get(fromId); java.util.Iterator<String> toIdIterator = toIds.iterator(); while (toIdIterator.hasNext()) { String tid = toIdIterator.next(); LWNode fromNode = dataRowNodes.get(fromId); LWNode toNode = dataRowNodes.get(tid); if (fromNode !=null && toNode !=null) { LWLink link = new LWLink(fromNode,toNode); VUE.getActiveMap().add(link); } } } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }; }); } @SuppressWarnings("unchecked") public static void addNotesToMap(final String content) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // Reader reader = openReader(); javax.xml.parsers.DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(true); factory.setIgnoringComments(true); //factory.setCoalescing(true); factory.setValidating(false); // We don't use is.setEncoding(), as openReader will already have handled that // is.setCharacterStream(reader); InputStream is; try { is = new java.io.ByteArrayInputStream(content.getBytes("UTF-8")); final org.w3c.dom.Document doc = factory.newDocumentBuilder().parse((InputStream) is); NodeList nodeLst = doc.getElementsByTagName("note"); //build multimap of links HashMap<String,String> map = new HashMap<String,String>(); for (int s = 0; s < nodeLst.getLength(); s++) { Node fstNode = nodeLst.item(s); if (fstNode.getNodeType() == Node.ELEMENT_NODE) { NamedNodeMap atts = fstNode.getAttributes(); Node n = atts.item(0); NodeList noteList = fstNode.getChildNodes(); map.put(n.getNodeValue(), ((Node)noteList.item(0)).getNodeValue().trim()); // System.out.println("puts : " + n.getNodeValue() +"," +fstNode.getNodeValue()); } } java.util.Collection<LWComponent> comps = VUE.getActiveMap().getAllDescendents(); java.util.Iterator<LWComponent> iter = comps.iterator(); //build map of data row nodes HashMap<String,LWNode> dataRowNodes = new HashMap<String,LWNode>(); while (iter.hasNext()) { LWComponent comp = iter.next(); if (comp.isDataRowNode()) { String fromId= comp.getDataValue("id"); dataRowNodes.put(fromId, (LWNode)comp); } } //draw links java.util.Set<String> keys = map.keySet(); java.util.Iterator<String> notesIterator = keys.iterator(); while (notesIterator.hasNext()) { String id = notesIterator.next(); LWNode fromNode = dataRowNodes.get(id); if (fromNode !=null) { String note = map.get(id); fromNode.setNotes(note); } } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }; }); } public static String getActiveResourceTitle() { LWSelection selection = VUE.getActiveViewer().getSelection(); if (!selection.isEmpty()) { return selection.get(0).getResource().getTitle(); } else return null; } private static boolean sourceAdded = false; @SuppressWarnings("unchecked") public static void addZoteroDatasource(final String collectionName, final String fileString, final boolean addToMap) { sourceAdded=false; // AccessController.doPrivileged(new PrivilegedAction() { // public Object run() { try { DataSourceList l = DataSetViewer.getDataSetList(); int length = l.getModel().getSize(); for (int i = 0; i<length; i++) { Object o = l.getModel().getElementAt(i); if (o instanceof XmlDataSource) { final XmlDataSource xmlds = (XmlDataSource)o; if (xmlds.getDisplayName().equals(collectionName) && xmlds.getAddress().equals(fileString) && !sourceAdded) { sourceAdded=true; //we already have it in the list refresh it and move on... VUE.getContentDock().setVisible(true); VUE.getContentPanel().showDatasetsTab(); SwingUtilities.invokeLater(new Runnable() { public void run() { VUE.getContentPanel().getDSBrowser().getDataSetViewer().setActiveDataSource(xmlds); VUE.getContentPanel().getDSBrowser().getDataSetViewer().refreshBrowser(); }}); if (addToMap) { boolean added = false; int tries = 0; while (!added && tries < 10) { try { added = true; List<LWComponent> nodes = DataAction.makeRowNodes(xmlds.getSchema()); LWMap map = VUE.getActiveMap(); for(LWComponent component: nodes) { map.add(component); } LayoutAction.random.act(new LWSelection(nodes)); } catch(NullPointerException npe) { System.out.println(npe.toString()); added = false; tries++; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }//end addToMap // }}); //return null; } } }//end for if (sourceAdded) return; // return new Object(); String xml; final tufts.vue.DataSource ds = new XmlDataSource(collectionName, fileString); Properties props = new Properties(); props.put("displayName", collectionName); props.put("name", collectionName); props.put("address", fileString); props.put("item_path", "zoteroCollection.zoteroItem"); props.put("key_field", "zoteroCollection.zoteroItem.id"); ds.setConfiguration(props); final BrowseDataSource bds = (BrowseDataSource)ds; VUE.getContentDock().setVisible(true); VUE.getContentPanel().showDatasetsTab(); DataSetViewer.getDataSetList().addOrdered(ds); SwingUtilities.invokeLater(new Runnable(){ public void run() { VUE.getContentPanel().getDSBrowser().getDataSetViewer().setActiveDataSource(ds); }}); DataSourceViewer.saveDataSourceViewer(); if (addToMap) { XmlDataSource xmlds = (XmlDataSource)ds; boolean added = false; int tries = 0; while (!added && tries < 10) { try { // DataTree.this.addNewRowsToMap(); added = true; List<LWComponent> nodes = DataAction.makeRowNodes(xmlds.getSchema()); LWMap map = VUE.getActiveMap(); for(LWComponent component: nodes) { map.add(component); } LayoutAction.random.act(new LWSelection(nodes)); } catch(NullPointerException npe) { added = false; tries++; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } // } // }); } catch (Exception e) { e.printStackTrace(); } //return null; // } // }); } public static void displayMap(String urlString) { innerDisplayMap(urlString); } public static void displayLocalMap(String fileString) { innerDisplayLocalMap(fileString); } @SuppressWarnings("unchecked") private static void innerDisplayMap(final String urlString) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { /* * try { File tempFile = null; tempFile = * File.createTempFile(new * Long(System.currentTimeMillis()).toString(), null); * InputStream io = null; * * io = getInputStream(urlString); byte[] buf = new byte[256]; * int read = 0; java.io.FileOutputStream fos = null; fos = new * java.io.FileOutputStream(tempFile); * * while ((read = io.read(buf)) > 0) { fos.write(buf, 0, read); } */ URL url; try { url = new URL(urlString); tufts.vue.action.OpenURLAction.displayMap(url); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } /* * tufts.vue.action.OpenAction.displayMap(tempFile); * } catch(Exception e) { e.printStackTrace(); } */ return null; } }); } @SuppressWarnings("unchecked") private static void innerDisplayLocalMap(final String fileString) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { tufts.vue.action.OpenAction.displayMap(new File(fileString)); return null; } }); } public static InputStream getInputStream(String fileName) throws IOException { InputStream input; if (fileName.startsWith("http:")) { URL url = new URL(fileName); URLConnection connection = url.openConnection(); input = connection.getInputStream(); } else { input = new FileInputStream(fileName); } return input; } protected static MapViewer getMapViewer() { return viewer; } protected static MapTabbedPane getMapTabbedPane() { return mMapTabbedPane; } }