001/*
002 * Copyright (c) 2004-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2015-08-24 22:44:14 +0000 (Mon, 24 Aug 2015) $' 
007 * '$Revision: 33630 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.kepler.gui.component;
031
032import java.awt.event.ActionEvent;
033import java.io.File;
034import java.io.IOException;
035
036import javax.swing.Action;
037import javax.swing.ImageIcon;
038import javax.swing.JOptionPane;
039import javax.swing.KeyStroke;
040
041import org.apache.commons.logging.Log;
042import org.apache.commons.logging.LogFactory;
043import org.kepler.gui.KeplerGraphFrame;
044import org.kepler.moml.NamedObjId;
045import org.kepler.objectmanager.ActorMetadata;
046import org.kepler.objectmanager.cache.CacheManager;
047import org.kepler.objectmanager.cache.CacheObjectInterface;
048import org.kepler.objectmanager.lsid.KeplerLSID;
049
050import diva.gui.GUIUtilities;
051import ptolemy.actor.gui.Configuration;
052import ptolemy.actor.gui.ModelDirectory;
053import ptolemy.actor.gui.PtolemyEffigy;
054import ptolemy.actor.gui.TableauFrame;
055import ptolemy.kernel.ComponentEntity;
056import ptolemy.kernel.CompositeEntity;
057import ptolemy.kernel.util.NamedObj;
058import ptolemy.moml.MoMLParser;
059import ptolemy.util.MessageHandler;
060import ptolemy.vergil.basic.BasicGraphFrame;
061import ptolemy.vergil.toolbox.FigureAction;
062
063/**
064 * This action opens a CompositeEntity.
065 */
066public class OpenCompositeAction extends FigureAction {
067
068        private static String DISPLAY_NAME = "Open";
069        private static String TOOLTIP = "Open";
070        private static ImageIcon LARGE_ICON = null;
071        private static KeyStroke ACCELERATOR_KEY = null;
072
073        // //////////////////////////////////////////////////////////////////////////////
074
075        private TableauFrame parent;
076
077        private KeplerLSID lsidToOpen;
078        
079        /** A NamedObj to open. */
080        private NamedObj _namedObjToOpen;
081        
082        /** The path of a MoML file to open. */
083        private String _path;
084        
085        /** MoMLParser to parse a MoML file. */
086        private MoMLParser _parser;
087
088        public void setLsidToOpen(KeplerLSID lsid) {
089                lsidToOpen = lsid;
090        }
091
092        public KeplerLSID getLsidToOpen() {
093                return lsidToOpen;
094        }
095        
096        /** Set the path of a MoML file to be opened. */
097        public void setFilePath(String path) {
098            _path = path;
099        }
100
101        private final static Log log = LogFactory.getLog(OpenCompositeAction.class);
102        private static final boolean isDebugging = log.isDebugEnabled();
103
104        /**
105         * Constructor
106         * 
107         *@param parent
108         *            the "frame" (derived from ptolemy.gui.Top) where the menu is
109         *            being added.
110         */
111        public OpenCompositeAction(TableauFrame parent) {
112                super("Open Archive (KAR)");
113                if (parent == null) {
114                        IllegalArgumentException iae = new IllegalArgumentException(
115                                        "OpenCompositeAction constructor received NULL argument for TableauFrame");
116                        iae.fillInStackTrace();
117                        throw iae;
118                }
119                this.parent = parent;
120
121                this.putValue(Action.NAME, DISPLAY_NAME);
122                this.putValue(GUIUtilities.LARGE_ICON, LARGE_ICON);
123                this.putValue("tooltip", TOOLTIP);
124                this.putValue(GUIUtilities.ACCELERATOR_KEY, ACCELERATOR_KEY);
125        }
126
127        public OpenCompositeAction(String name, TableauFrame parent) {
128            super(name);
129            this.parent = parent;
130        }
131        
132        /**
133         * Invoked when an action occurs.
134         * 
135         *@param e
136         *            ActionEvent
137         */
138        public void actionPerformed(ActionEvent e) {
139                super.actionPerformed(e);
140
141                if(_path != null) {
142                    if(_parser == null) {
143                        _parser = new MoMLParser();
144                    }
145                    _parser.reset();
146                    try {
147                _namedObjToOpen = _parser.parseFile(_path);
148            } catch (Exception exception) {
149                MessageHandler.error("Unable to open " + _path, exception);
150            }
151                }
152                
153                if(_namedObjToOpen != null) {
154                    Configuration configuration = parent.getConfiguration();
155                    if(configuration != null) {
156                        try {
157                            configuration.openModel(_namedObjToOpen);
158                } catch (Exception exception) {
159                    MessageHandler.error("Unable to open " + _namedObjToOpen.getName(), exception);
160                    return;
161                }                   
162            }
163
164                    // if we successfully opened a file, update the history menu and
165                    // set the last directory.
166                    if(_path != null) {
167                // update the history menu
168                if(parent instanceof KeplerGraphFrame) {
169                    try {
170                        ((KeplerGraphFrame)parent).updateHistory(_path);
171                    } catch (IOException exception) {
172                        MessageHandler.error("Unable to update history menu.", exception);
173                    }
174                }
175                if(parent instanceof BasicGraphFrame) {
176                    ((BasicGraphFrame)parent).setLastDirectory(new File(_path).getParentFile());
177                }
178                    }
179                    
180                    return;
181                }
182                
183                try {
184
185                        KeplerLSID lsid = getLsidToOpen();
186
187                        CacheManager cache = CacheManager.getInstance();
188
189                        // get the object from the cache (it is GraphicalActorMetadata even
190                        // though it is a workflow)
191                        CacheObjectInterface co = cache.getObject(lsid);
192                        if (co == null) {
193
194                                if (isDebugging)
195                                        log.debug(lsid + " was not found in the cache");
196
197                        } else {
198
199                                Object o = co.getObject();
200                                if (isDebugging)
201                                        log.debug(o.getClass().getName());
202
203                                if (o instanceof ActorMetadata) {
204                                        ActorMetadata am = (ActorMetadata) o;
205                                        try {
206                                                // get the workflow from the metadata
207                                                NamedObj entity = am.getActorAsNamedObj(null);
208
209                                                if (isDebugging)
210                                                        log.debug(entity.getName() + " "
211                                                                        + NamedObjId.getIdFor(entity) + " "
212                                                                        + entity.getClass().getName());
213                                                if (entity instanceof CompositeEntity) {
214                                                        if (isDebugging)
215                                                                log.debug("Opening CompositeEntity");
216
217                                                        // get the xml representation - needs parsing to be
218                                                        // correct!
219                                                        String moml = entity.exportMoML();
220                                                        MoMLParser parser = new MoMLParser();
221                                                        entity = parser.parse(moml);
222
223                                                        Configuration configuration = parent
224                                                                        .getConfiguration();
225
226                                                        // TODO check on this
227                                                        // ----begin questionable title bar code:
228                                                        PtolemyEffigy effigy = new PtolemyEffigy(
229                                                                        configuration.workspace());
230                                                        effigy.setModel(entity);
231                                                        ModelDirectory directory = (ModelDirectory) configuration
232                                                                        .getEntity("directory");
233                                                        effigy.setName(entity.getName()); 
234                                                        // is this the right name for the effigy?
235                                                        effigy.identifier.setExpression(entity.getName());
236                                                        if (directory != null) {
237                                                                if (directory.getEntity(entity.getName()) != null) {
238                                                                        // Name is already taken.
239                                                                        int count = 2;
240                                                                        String newName = effigy.getName() + " "
241                                                                                        + count;
242                                                                        while (directory.getEntity(newName) != null) {
243                                                                                newName = effigy.getName() + " "
244                                                                                                + ++count;
245                                                                        }
246                                                                        effigy.setName(newName);
247                                                                }
248                                                        }
249                                                        effigy.setContainer(directory);
250                                                        // ---end questionable title bar code
251
252                                                        // open a new window for the workflow
253                                                        configuration.openModel(entity);
254                                                } else if (entity instanceof ComponentEntity) {
255                                                        // TODO handle opening of ComponentEntities??
256                                                        JOptionPane.showMessageDialog(null, "This component is not openable.");
257                                                } else {
258                                                        if (isDebugging)
259                                                                log.debug("Not a CompositeEntity");
260                                                        JOptionPane.showMessageDialog(null, "This component is not openable.");
261                                                }
262
263                                        } catch (Exception ex) {
264                                                ex.printStackTrace();
265                                                log.error("error opening the workflow: "
266                                                                + ex.getMessage());
267                                        }
268                                } else {
269                                        JOptionPane.showMessageDialog(null, "This component is not openable.");
270                                }
271                        }
272                } catch (Exception exc) {
273                        exc.printStackTrace();
274                }
275        }
276
277    public void setNamedObjToOpen(NamedObj obj) {
278        _namedObjToOpen = obj;
279    }
280}