001    /*
002     * $Id: JythonManager.java,v 1.12 2012/03/28 14:59:29 jbeavers Exp $
003     *
004     * This file is part of McIDAS-V
005     *
006     * Copyright 2007-2012
007     * Space Science and Engineering Center (SSEC)
008     * University of Wisconsin - Madison
009     * 1225 W. Dayton Street, Madison, WI 53706, USA
010     * https://www.ssec.wisc.edu/mcidas
011     * 
012     * All Rights Reserved
013     * 
014     * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015     * some McIDAS-V source code is based on IDV and VisAD source code.  
016     * 
017     * McIDAS-V is free software; you can redistribute it and/or modify
018     * it under the terms of the GNU Lesser Public License as published by
019     * the Free Software Foundation; either version 3 of the License, or
020     * (at your option) any later version.
021     * 
022     * McIDAS-V is distributed in the hope that it will be useful,
023     * but WITHOUT ANY WARRANTY; without even the implied warranty of
024     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025     * GNU Lesser Public License for more details.
026     * 
027     * You should have received a copy of the GNU Lesser Public License
028     * along with this program.  If not, see http://www.gnu.org/licenses.
029     */
030    package edu.wisc.ssec.mcidasv;
031    
032    import static ucar.unidata.util.GuiUtils.makeMenu;
033    import static ucar.unidata.util.GuiUtils.makeMenuItem;
034    import static ucar.unidata.util.MenuUtil.MENU_SEPARATOR;
035    
036    import java.util.ArrayList;
037    import java.util.List;
038    import java.util.Map;
039    
040    import org.python.util.PythonInterpreter;
041    
042    import org.slf4j.Logger;
043    import org.slf4j.LoggerFactory;
044    
045    import edu.wisc.ssec.mcidasv.util.CollectionHelpers;
046    
047    import ucar.unidata.data.DataSource;
048    import ucar.unidata.data.DescriptorDataSource;
049    import ucar.unidata.idv.IntegratedDataViewer;
050    import ucar.unidata.idv.ui.ImageGenerator;
051    import ucar.unidata.idv.ui.JythonShell;
052    
053    public class JythonManager extends ucar.unidata.idv.JythonManager {
054    
055        /** Trusty logging object. */
056        private static final Logger logger = LoggerFactory.getLogger(JythonManager.class);
057    
058        private JythonShell jythonShell;
059        
060        /**
061         * Create the manager and call initPython.
062         *
063         * @param idv The IDV
064         */
065        public JythonManager(IntegratedDataViewer idv) {
066            super(idv);
067        }
068    
069        /**
070         * Create a Jython shell, if one doesn't already exist. This will also 
071         * bring the window {@literal "to the front"} of the rest of the McIDAS-V
072         * session.
073         *
074         * @return JythonShell object for interactive Jython usage.
075         */
076        public JythonShell createShell() {
077            if (jythonShell == null) {
078                jythonShell = new JythonShell(getIdv());
079                
080            }
081            jythonShell.toFront();
082            return jythonShell;
083        }
084    
085        @Override public PythonInterpreter createInterpreter() {
086            PythonInterpreter interpreter = super.createInterpreter();
087            return interpreter;
088        }
089    
090        @Override public void removeInterpreter(PythonInterpreter interpreter) {
091            super.removeInterpreter(interpreter);
092            if (jythonShell != null && jythonShell.getInterpreter().equals(interpreter)) {
093                jythonShell.close();
094                jythonShell = null;
095            }
096        }
097    
098        /**
099         * Overridden so that McIDAS-V can inject a variable named {@code _idv}
100         * into {@code interpreter's} globals.
101         * 
102         * @param interpreter Jython interpreter being initialized by the IDV. Cannot be {@code null}.
103         */
104        @Override protected void initBasicInterpreter(PythonInterpreter interpreter) {
105            interpreter.set("_idv", getIdv());
106            interpreter.set("idv", getIdv());
107            super.initBasicInterpreter(interpreter);
108        }
109    
110        /**
111         * Overridden so that McIDAS-V can add an {@code islInterpreter} object
112         * to the interpreter's locals (before executing the c ontents of {@code}.
113         * 
114         * @param code Jython code to evaluate. {@code null} is probably a bad idea.
115         * @param properties {@code String->Object} pairs to insert into the 
116         * locals. Parameter may be {@code null}.
117         */
118        @SuppressWarnings("unchecked") // dealing with idv code that predates generics.
119        @Override public void evaluateTrusted(String code, Map<String, Object> properties) {
120            if (properties == null) {
121                properties = CollectionHelpers.newMap();
122            }
123            if (!properties.containsKey("islInterpreter")) {
124                properties.put("islInterpreter", new ImageGenerator(getIdv()));
125            }
126            if (!properties.containsKey("_idv")) {
127                properties.put("_idv", getIdv());
128            }
129            if (!properties.containsKey("idv")) {
130                properties.put("idv", getIdv());
131            }
132            super.evaluateTrusted(code, properties);
133        }
134    
135        /**
136         * Return the list of menu items to use when the user has clicked on a 
137         * formula {@link DataSource}.
138         * 
139         * @param dataSource The data source clicked on.
140         * 
141         * @return {@link List} of menu items.
142         */
143        @SuppressWarnings("unchecked") // dealing with idv code that predates generics.
144        @Override public List doMakeFormulaDataSourceMenuItems(DataSource dataSource) {
145            List menuItems = new ArrayList(100);
146            menuItems.add(makeMenuItem("Create Formula", this, "showFormulaDialog"));
147            List editItems;
148            if (dataSource instanceof DescriptorDataSource) {
149                editItems = doMakeEditMenuItems((DescriptorDataSource)dataSource);
150            }
151            else {
152                editItems = doMakeEditMenuItems();
153            }
154            menuItems.add(makeMenu("Edit Formulas", editItems));
155            menuItems.add(MENU_SEPARATOR);
156            menuItems.add(makeMenuItem("Jython Library", this, "showJythonEditor"));
157            menuItems.add(makeMenuItem("Jython Shell", this, "createShell"));
158            menuItems.add(MENU_SEPARATOR);
159            menuItems.add(makeMenuItem("Import", this, "importFormulas"));
160            menuItems.add(makeMenuItem("Export", this, "exportFormulas"));
161            return menuItems;
162        }
163    
164    }