001/*
002 * Copyright (c) 2005-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: welker $'
006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 
007 * '$Revision: 24234 $'
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.resurgence.actor;
031
032import java.io.File;
033import java.io.FileInputStream;
034import java.io.FileOutputStream;
035
036import ptolemy.actor.TypedAtomicActor;
037import ptolemy.actor.TypedIOPort;
038import ptolemy.actor.parameters.PortParameter;
039import ptolemy.data.BooleanToken;
040import ptolemy.data.StringToken;
041import ptolemy.data.expr.Parameter;
042import ptolemy.data.type.BaseType;
043import ptolemy.kernel.CompositeEntity;
044import ptolemy.kernel.util.IllegalActionException;
045import ptolemy.kernel.util.NameDuplicationException;
046
047//////////////////////////////////////////////////////////////////////////
048//// FileCopier
049
050/**
051 * This actor copies a file with path name into a directory that is given via a
052 * port or as a parameter. If this directory does not exist, it is created. The
053 * user can decide if an existing file with the same name is overwritten. The
054 * file may also be moved instead of copied. The corresponding new file with
055 * path name is given out.
056 * 
057 * @author Wibke Sudholt, University and ETH Zurich, November 2004
058 * @version $Id: FileCopier.java 24234 2010-05-06 05:21:26Z welker $
059 */
060public class FileCopier extends TypedAtomicActor {
061
062        /**
063         * Construct a FileCopier with the given container and name.
064         * 
065         * @param container
066         *            The container.
067         * @param name
068         *            The name of this actor.
069         * @exception IllegalActionException
070         *                If the entity cannot be contained by the proposed
071         *                container.
072         * @exception NameDuplicationException
073         *                If the container already has an actor with this name.
074         */
075        public FileCopier(CompositeEntity container, String name)
076                        throws NameDuplicationException, IllegalActionException {
077                super(container, name);
078
079                directory = new PortParameter(this, "directory");
080                directory.setStringMode(true);
081
082                oldFile = new TypedIOPort(this, "oldFile", true, false);
083                oldFile.setTypeEquals(BaseType.STRING);
084
085                newFile = new TypedIOPort(this, "newFile", false, true);
086                newFile.setTypeEquals(BaseType.STRING);
087
088                overwrite = new Parameter(this, "Overwrite existing", new BooleanToken(
089                                false));
090                overwrite.setTypeEquals(BaseType.BOOLEAN);
091
092                move = new Parameter(this, "Move files", new BooleanToken(false));
093                move.setTypeEquals(BaseType.BOOLEAN);
094
095                _attachText("_iconDescription", "<svg>\n"
096                                + "<rect x=\"-25\" y=\"-20\" " + "width=\"50\" height=\"40\" "
097                                + "style=\"fill:white\"/>\n"
098                                + "<polygon points=\"-15,-10 -12,-10 -8,-14 -1,-14 3,-10"
099                                + " 15,-10 15,10, -15,10\" " + "style=\"fill:red\"/>\n"
100                                + "</svg>\n");
101        }
102
103        // /////////////////////////////////////////////////////////////////
104        // // ports and parameters ////
105
106        /**
107         * The port or parameter, which is a string with the directory name.
108         */
109        public PortParameter directory = null;
110        /**
111         * The input port, which contains the old file path and name.
112         */
113        public TypedIOPort oldFile = null;
114        /**
115         * The output port, which contains the new file path and name.
116         */
117        public TypedIOPort newFile = null;
118        /**
119         * The boolean parameter, which decides if existing files are overwritten.
120         */
121        public Parameter overwrite = null;
122        /**
123         * The boolean parameter, which decides if the files are moved instead of
124         * copied.
125         */
126        public Parameter move = null;
127
128        // /////////////////////////////////////////////////////////////////
129        // // public methods ////
130
131        /**
132         * Take the files and put them into the new directory.
133         * 
134         * @exception IllegalActionException
135         *                If there's no director or if file copying does not work.
136         */
137        public void fire() throws IllegalActionException {
138                super.fire();
139                // Get all information.
140                directory.update();
141                _path = ((StringToken) directory.getToken()).stringValue();
142                _original = ((StringToken) oldFile.get(0)).stringValue();
143                _overwriteFile = ((BooleanToken) overwrite.getToken()).booleanValue();
144                _moveFile = ((BooleanToken) move.getToken()).booleanValue();
145                // Make the directory if necessary.
146                _dir = new File(_path);
147                if (!_dir.exists()) {
148                        _mkdirsSuccess = _dir.mkdirs();
149                        if (!_mkdirsSuccess) {
150                                throw new IllegalActionException(this, "Directory " + _dir
151                                                + " was not successfully made.");
152                        }
153                } else {
154                        if (!_dir.isDirectory() || !_dir.canWrite()) {
155                                throw new IllegalActionException(this,
156                                                "Cannot write into directory " + _dir + ".");
157                        }
158                }
159                // Move or copy the file.
160                _file = new File(_original);
161                _target = new File(_dir, _file.getName());
162                if (_overwriteFile || !_target.exists()) {
163                        try {
164                                if (_moveFile) {
165                                        _renameSuccess = _file.renameTo(_target);
166                                        if (!_renameSuccess) {
167                                                throw new IllegalActionException(this, "File " + _file
168                                                                + " was not successfully moved.");
169                                        }
170                                } else {
171                                        _inStream = new FileInputStream(_file);
172                                        _outStream = new FileOutputStream(_target);
173                                        int i = 0;
174                                        while ((i = _inStream.read()) != -1) {
175                                                _outStream.write(i);
176                                        }
177                                        _inStream.close();
178                                        _outStream.close();
179                                }
180                                _copy = new StringToken(_target.getCanonicalPath());
181                        } catch (Exception ex) {
182                                _debug("File cannot be copied or moved.");
183                        }
184                        newFile.send(0, _copy);
185                }
186        }
187
188        // /////////////////////////////////////////////////////////////////
189        // // protected members ////
190
191        // /////////////////////////////////////////////////////////////////
192        // // private methods ////
193
194        // /////////////////////////////////////////////////////////////////
195        // // private members ////
196
197        private String _path;
198        private String _original;
199        private boolean _overwriteFile;
200        private boolean _moveFile;
201        private File _dir;
202        private boolean _mkdirsSuccess;
203        private File _file;
204        private File _target;
205        private StringToken _copy;
206        private boolean _renameSuccess;
207        private FileInputStream _inStream;
208        private FileOutputStream _outStream;
209}