001/*
002 * Copyright (c) 2004-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2012-11-26 22:19:36 +0000 (Mon, 26 Nov 2012) $' 
007 * '$Revision: 31113 $'
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.cipres.kepler;
031
032// Ptolemy package
033import java.awt.Color;
034import java.io.File;
035
036import javax.swing.JFileChooser;
037
038import org.cipres.util.Config;
039import org.cipres.util.file.cipresFile;
040
041import ptolemy.actor.TypedAtomicActor;
042import ptolemy.actor.TypedIOPort;
043import ptolemy.data.StringToken;
044import ptolemy.data.expr.FileParameter;
045import ptolemy.data.type.BaseType;
046import ptolemy.gui.JFileChooserBugFix;
047import ptolemy.gui.PtFileChooser;
048import ptolemy.kernel.CompositeEntity;
049import ptolemy.kernel.util.IllegalActionException;
050import ptolemy.kernel.util.NameDuplicationException;
051
052//////////////////////////////////////////////////////////////////////////
053//// NexusFileReader
054/**
055 * The NexusFileReader actor reads a Nexus file from the local file system and
056 * sends the file content as a string token.
057 * 
058 * @author Zhijie Guan
059 * @version $Id: NexusFileReader.java 31113 2012-11-26 22:19:36Z crawl $
060 */
061
062public class NexusFileReader extends TypedAtomicActor {
063
064        /**
065         * Construct a NexusFileReader actor with the given container and name.
066         * 
067         * @param container
068         *            The container.
069         * @param name
070         *            The name of this actor. by the proposed container.
071         * @exception NameDuplicationException
072         *                If the container already has an actor with this name.
073         */
074
075        public NexusFileReader(CompositeEntity container, String name)
076                        throws NameDuplicationException, IllegalActionException {
077                super(container, name);
078
079                // construct the input port inputTrigger
080                inputTrigger = new TypedIOPort(this, "inputTrigger", true, false);
081                inputTrigger.setDisplayName("Trigger");
082                inputTrigger.setTypeEquals(BaseType.GENERAL);
083
084                // construct the output port outputFileContent
085                outputFileContent = new TypedIOPort(this, "outputFileContent", false,
086                                true);
087                outputFileContent.setDisplayName("File Content");
088                // Set the type constraint.
089                outputFileContent.setTypeEquals(BaseType.GENERAL);
090
091                // construct the parmeter fileNamePar
092                // set the default value of this parameter as an empty string ("")
093                // since this parameter should only accept a string value
094                fileNamePar = new FileParameter(this, "fileNamePar");
095                fileNamePar.setDisplayName("Nexus File Name");
096
097                _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" "
098                                + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n"
099                                + "</svg>\n");
100
101        }
102
103        // /////////////////////////////////////////////////////////////////
104        // // ports and parameters ////
105
106        /**
107         * A trigger signal that enables the actor is passed to the NexusFileReader
108         * actor through this input port. This port is an input port of type
109         * GENERAL.
110         */
111        public TypedIOPort inputTrigger = null;
112
113        /**
114         * The Nexus file content is sent out through this output port. This port is
115         * an output port of type GENERAL.
116         */
117        public TypedIOPort outputFileContent = null;
118
119        /**
120         * The Nexus file name is set in this parameter. The NexusFileReader actor
121         * opens and reads the file specified by this parameter and sends out the
122         * content through the outputFileContent port. If the user leaves this
123         * parameter empty, the NexusFileReader will pop up a file chooser dialog to
124         * let the user specify the file in the local file system.
125         */
126        public FileParameter fileNamePar = null;
127
128        // /////////////////////////////////////////////////////////////////
129        // // functional variables ////
130
131        // /////////////////////////////////////////////////////////////////
132        // // public methods ////
133
134        /**
135         * Send the content of the Nexus file to the output.
136         * 
137         * @exception IllegalActionException
138         *                If it is thrown by the send() method sending out the
139         *                token.
140         */
141        public void fire() throws IllegalActionException {
142                super.fire();
143
144                if (inputTrigger.hasToken(0)) {
145                        inputTrigger.get(0);
146                        // get the nexus file name
147                        String fileNameStr = ((StringToken) fileNamePar.getToken())
148                                        .stringValue();
149                        if (fileNameStr.length() == 0) {
150                            // Avoid white boxes in file chooser, see
151                        // http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3801
152                            JFileChooserBugFix jFileChooserBugFix = new JFileChooserBugFix();
153                            Color background = null;
154                            try {
155                                background = jFileChooserBugFix.saveBackground();
156
157                                // if the file name is empty, the actor pops up a file chooser
158                                // dialog
159                                PtFileChooser fileChooser = new PtFileChooser(null, "Choose Nexus File", JFileChooser.OPEN_DIALOG);
160                                fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
161                                Config config = Config.getInstance();
162                                if(config != null) {
163                                        fileChooser.setCurrentDirectory(new File(config.getDefaultNexusFileDir()));                                     
164                                }
165                                if (fileChooser.showDialog(null, "Open") == JFileChooser.APPROVE_OPTION) {
166                                        fileNameStr = fileChooser.getSelectedFile()
167                                                        .getAbsolutePath();
168                                }
169                            } finally {
170                                jFileChooserBugFix.restoreBackground(background);
171                            }
172                        }
173                        try {
174                                // This block is for sending file content
175                                if(fileNameStr.isEmpty()) {
176                                        throw new IllegalActionException(this, "Must specify input file name.");
177                                }
178                                cipresFile cf = new cipresFile(fileNameStr);
179                                StringToken fileContentToken = new StringToken(cf.getContent());
180                                outputFileContent.send(0, fileContentToken);
181
182                        } catch (Exception ex) {
183                                ex.printStackTrace();
184                        }
185                }
186        }
187
188        /**
189         * Post fire the actor. Return false to indicated that the process has
190         * finished. If it returns true, the process will continue indefinitely.
191         */
192        public boolean postfire() {
193                return false;
194        }
195}