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:47:39 +0000 (Mon, 24 Aug 2015) $' 
007 * '$Revision: 33633 $'
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.srb;
031
032import java.io.IOException;
033import java.util.Iterator;
034import java.util.LinkedList;
035import java.util.List;
036import java.util.Map;
037import java.util.TreeMap;
038import java.util.Vector;
039
040import edu.sdsc.grid.io.srb.SRBFile;
041import edu.sdsc.grid.io.srb.SRBFileSystem;
042import ptolemy.actor.IOPort;
043import ptolemy.actor.NoTokenException;
044import ptolemy.actor.TypedAtomicActor;
045import ptolemy.actor.TypedIOPort;
046import ptolemy.data.ArrayToken;
047import ptolemy.data.BooleanToken;
048import ptolemy.data.ObjectToken;
049import ptolemy.data.StringToken;
050import ptolemy.data.Token;
051import ptolemy.data.expr.Parameter;
052import ptolemy.data.expr.SingletonParameter;
053import ptolemy.data.expr.StringParameter;
054import ptolemy.data.type.ArrayType;
055import ptolemy.data.type.BaseType;
056import ptolemy.gui.GraphicalMessageHandler;
057import ptolemy.kernel.CompositeEntity;
058import ptolemy.kernel.util.Attribute;
059import ptolemy.kernel.util.IllegalActionException;
060import ptolemy.kernel.util.NameDuplicationException;
061
062//////////////////////////////////////////////////////////////////////////
063//// SProxy
064/**
065 * <p>
066 * Executes a proxy command. Currently supporteds command: 'list directory',
067 * 'copy', 'move', 'remove', 'replicate', 'create directory', 'remove
068 * directory', 'change mode'.
069 * </p>
070 * <p>
071 * The actor accepts a reference to the SRB files system, and a desired command
072 * with its input ports. Outputs the command result along with an exit status.
073 * </p>
074 * <p>
075 * <b> COMMANDS DESCRIPTIONS:</b>
076 * </p>
077 * <p>
078 * <b>List directory:</b> Lists a remote directory content.
079 * </p>
080 * <p>
081 * Inputs: path: [string]. Remote paths to list.
082 * </p>
083 * <p>
084 * Output: listedFiles : [string]. Arrays of the contained files paths.
085 * </p>
086 * <p>
087 * exitCode : string.
088 * </p>
089 * <p>
090 * Option: outputEachFileSeparately. Whether to broadcast each file path
091 * sepearately or the whole list at once.
092 * </p>
093 * <p>
094 * <b>Copy/Move:</b> Copys or moves files to a new path. Returns the new file
095 * paths. recursively copies/moves directories.
096 * </p>
097 * <p>
098 * Inputs: path: [string]. Original remote file paths.
099 * </p>
100 * <p>
101 * newPath: string. Location to copy/move.
102 * </p>
103 * <p>
104 * Output: copiedFiles/movedFiles : [string]. Arrays of the new file paths.
105 * </p>
106 * <p>
107 * <b>Remove/Remove directory:</b> Removes files/directories. Non-empty
108 * directories are recursively removed by remove r.
109 * </p>
110 * <p>
111 * Inputs: path: [string]. Remote file paths.
112 * </p>
113 * <p>
114 * Option: -r ; recursively removes files.
115 * </p>
116 * <p>
117 * forward ; output an array of the removed files parent directory paths.
118 * </p>
119 * <p>
120 * <b>Create directory:</b> Creates new directories. Returns the new directory
121 * path.
122 * </p>
123 * <p>
124 * Inputs: path: [string]. New directories paths.
125 * </p>
126 * <p>
127 * Output: dirPath: Created directories paths.
128 * </p>
129 * <p>
130 * <b>Replicate:</b> Replicates a file/directory to a new resource.
131 * </p>
132 * <p>
133 * Inputs: path: [string]. The files to be replicated.
134 * </p>
135 * <p>
136 * newPath: [string]. The resource to replicate to.
137 * </p>
138 * <p>
139 * Output: newResource: string. The files new resource.
140 * </p>
141 * <p>
142 * <b>Change mode:</b> Changes the permissions of a file or a directory.
143 * </p>
144 * <p>
145 * Inputs: path: [string]. Files paths.
146 * </p>
147 * <p>
148 * permission: string
149 * </p>
150 * <p>
151 * userName: string. To grant permission to.
152 * </p>
153 * <p>
154 * mdasDomain: string. The metadata domain.
155 * </p>
156 * <p>
157 * Output: exitPath: [string]. The files paths.
158 * 
159 * </p>
160 * 
161 * @author Efrat Jaeger
162 * @version $Id: SProxy.java 33633 2015-08-24 22:47:39Z crawl $
163 * @category.name srb
164 */
165
166public class SProxy extends TypedAtomicActor {
167
168        /**
169         * Construct a constant source with the given container and name. Create the
170         * <i>value</i> parameter, initialize its value to the default value of an
171         * IntToken with value 1.
172         * 
173         * @param container
174         *            The container.
175         * @param name
176         *            The name of this actor.
177         * @exception IllegalActionException
178         *                If the entity cannot be contained by the proposed
179         *                container.
180         * @exception NameDuplicationException
181         *                If the container already has an actor with this name.
182         */
183        public SProxy(CompositeEntity container, String name)
184                        throws NameDuplicationException, IllegalActionException {
185                super(container, name);
186
187                SRBFileSystem = new TypedIOPort(this, "SRBFileSystem", true, false);
188                SRBFileSystem.setTypeEquals(BaseType.GENERAL);
189                new Attribute(SRBFileSystem, "_showName");
190
191                path = new TypedIOPort(this, "path", true, false);
192                path.setTypeEquals(new ArrayType(BaseType.STRING));
193                Attribute tmp = new Attribute(path, "_showName");
194
195                newPath = new TypedIOPort(this, "newPath", true, false);
196                // newPath.setContainer(null);
197                newPath.setTypeEquals(BaseType.STRING);
198                // new Attribute(newPath, "_showName");
199                hideNewPath = new SingletonParameter(newPath, "_hide");
200                hideNewPath.setToken(BooleanToken.TRUE);
201
202                permission = new TypedIOPort(this, "permission", true, false);
203                // permission.setContainer(null);
204                permission.setTypeEquals(BaseType.STRING);
205                // new Attribute(permission, "_showName");
206                hidePermission = new SingletonParameter(permission, "_hide");
207                hidePermission.setToken(BooleanToken.TRUE);
208
209                userName = new TypedIOPort(this, "userName", true, false);
210                // userName.setContainer(null);
211                userName.setTypeEquals(BaseType.STRING);
212                // new Attribute(userName, "_showName");
213                hideUserName = new SingletonParameter(userName, "_hide");
214                hideUserName.setToken(BooleanToken.TRUE);
215
216                mdasDomain = new TypedIOPort(this, "mdasDomain", true, false);
217                // mdasDomain.setContainer(null);
218                mdasDomain.setTypeEquals(BaseType.STRING);
219                // new Attribute(mdasDomain, "_showName");
220                hideMdasDomain = new SingletonParameter(mdasDomain, "_hide");
221                hideMdasDomain.setToken(BooleanToken.TRUE);
222
223                // output = new TypedIOPort(this, "output", false, true);
224                // output.setTypeEquals(new ArrayType(BaseType.STRING));
225                // new Attribute(output, "_showName");
226                // TODO: OUTPUT SHOULD BE SET DYNAMICALLY LIKE IN THE WS.
227
228                exitCode = new TypedIOPort(this, "exitCode", false, true);
229                exitCode.setTypeEquals(BaseType.STRING);
230                new Attribute(exitCode, "_showName");
231
232                command = new StringParameter(this, "command");
233                command.setExpression("list directory");
234                command.addChoice("list directory");
235                command.addChoice("copy");
236                command.addChoice("move");
237                command.addChoice("remove");
238                command.addChoice("replicate");
239                command.addChoice("create directory");
240                command.addChoice("remove directory");
241                command.addChoice("change mode");
242
243                // corrected way to create Parameters
244                outputEachFileSeparately = new Parameter(this,
245                                "outputEachFileSeparately", new BooleanToken(false));
246                outputEachFileSeparately
247                                .setDisplayName("output each path separately (for Sls)");
248                outputEachFileSeparately.setTypeEquals(BaseType.BOOLEAN);
249
250                // corrected way to create Parameters
251                forwardParentDir = new Parameter(this, "forwardParentDir",
252                                new BooleanToken(false));
253                forwardParentDir
254                                .setDisplayName("forward parent directory (for Srm/Srmdir)");
255                forwardParentDir.setTypeEquals(BaseType.BOOLEAN);
256
257                // corrected way to createParameters
258                _r = new Parameter(this, "_r", new BooleanToken(false));
259                _r.setDisplayName("-r (for Srm)");
260                _r.setTypeEquals(BaseType.BOOLEAN);
261
262                trigger = new TypedIOPort(this, "trigger", true, false);
263                // new Attribute(trigger, "_showName");
264                hideTrigger = new SingletonParameter(trigger, "_hide");
265                hideTrigger.setToken(BooleanToken.TRUE);
266
267                // Set the trigger Flag.
268                hasTrigger = new Parameter(this, "hasTrigger", new BooleanToken(false));
269                hasTrigger.setTypeEquals(BaseType.BOOLEAN);
270
271                singletons = new TreeMap();
272
273                singletons.put("trigger", hideTrigger);
274                singletons.put("newPath", hideNewPath);
275                singletons.put("permission", hidePermission);
276                singletons.put("userName", hideUserName);
277                singletons.put("mdasDomain", hideMdasDomain);
278
279                _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" "
280                                + "width=\"60\" height=\"30\" " + "style=\"fill:white\"/>\n"
281                                + "</svg>\n");
282
283        }
284
285        public SingletonParameter hideTrigger;
286        public SingletonParameter hideNewPath;
287        public SingletonParameter hidePermission;
288        public SingletonParameter hideUserName;
289        public SingletonParameter hideMdasDomain;
290
291        /**
292         * SRB file system reference.
293         */
294        public TypedIOPort SRBFileSystem;
295
296        /**
297         * Path to SRB file.
298         */
299        public TypedIOPort path;
300
301        /**
302         * New file path.
303         */
304        public TypedIOPort newPath;
305
306        /**
307         * Files permissions.
308         */
309        public TypedIOPort permission;
310        // public TypedIOPort output;
311
312        /**
313         * Execution exit code.
314         */
315        public TypedIOPort exitCode;
316        /**
317         * User name.
318         */
319        public TypedIOPort userName;
320
321        /**
322         * Meta data domain.
323         */
324        public TypedIOPort mdasDomain;
325
326        /**
327         * The proxy command to be performed.
328         */
329        public StringParameter command;
330
331        /**
332         * Specify whether to display the complete Sls result at once or each file
333         * separately.
334         */
335        public Parameter outputEachFileSeparately;
336
337        /**
338         * Specify whether to output the parent directories of removed
339         * files/directories or have a sink actor.
340         */
341        public Parameter forwardParentDir;
342
343        /**
344         * Specify whether to remove recursively.
345         */
346        public Parameter _r;
347
348        /**
349         * An input trigger.
350         */
351        public TypedIOPort trigger;
352
353        /**
354         * Specify whether to add a trigger port.
355         */
356        public Parameter hasTrigger;
357
358        // /////////////////////////////////////////////////////////////////
359        // // public methods ////
360
361        /**
362         * Callback for changes in attribute values. Set the action specified by the
363         * selected command.
364         * 
365         * @param a
366         *            The attribute that changed.
367         * @exception IllegalActionException
368         *                If the offsets array is not nondecreasing and nonnegative.
369         */
370        public void attributeChanged(Attribute at) throws IllegalActionException {
371                if (at == command) {
372                        // command changed flag
373                        boolean flag = true;// (!prevCmd.equals("") &&
374                                                                // !prevCmd.equals(command.getExpression()));
375                        String cmd = command.stringValue();
376                        prevCmd = cmd;
377                        // lists for adding removing ports by command.
378                        // The ports necessary for all commands are srbFileSystem, path and
379                        // exitCode.
380                        List reqInputPorts = new LinkedList();
381                        // List reqOutputPorts = new LinkedList();
382                        if (cmd.equals("list directory")) {
383                                if (flag) {
384                                        // reqOutputPorts.add("output");
385                                        _setInputPorts(reqInputPorts); // "listedFiles");
386                                        // add output port if not exists.
387                                        _setOutputPort("listedFiles");
388                                        // _addPorts(this.outputPortList(), reqOutputPorts);
389
390                                        /*
391                                         * if (output.getContainer() == null) { try {
392                                         * output.setContainer(this); } catch
393                                         * (NameDuplicationException ex) {
394                                         * GraphicalMessageHandler.message(ex.getMessage() +
395                                         * "Could not add input ports in the actor: " +
396                                         * this.getName() + " for command " + cmd); } }
397                                         */
398                                }
399                                _cmd = _LS;
400                        } else if (cmd.equals("copy")) {
401                                if (flag) {
402                                        reqInputPorts.add("newPath");
403                                        // reqOutputPorts.add("output");
404                                        _setInputPorts(reqInputPorts); // "copiedFiles"); // FIXME:
405                                                                                                        // or should this be new
406                                                                                                        // location??
407                                        // _addPorts(this.outputPortList(), reqOutputPorts);
408                                        _setOutputPort("copiedFiles");
409                                        try {
410                                                // newPath.setContainer(this);
411                                                hideNewPath.setToken(BooleanToken.FALSE);
412                                                // if (output.getContainer() == null)
413                                                // output.setContainer(this);
414                                        } catch (Exception ex) {
415                                                GraphicalMessageHandler.message(ex.getMessage()
416                                                                + "Could not add input ports in the actor: "
417                                                                + this.getName() + " for command " + cmd);
418                                        }
419                                }
420                                _cmd = _CP;
421                        } else if (cmd.equals("move")) {
422                                if (flag) {
423                                        reqInputPorts.add("newPath");
424                                        // reqOutputPorts.add("output");
425                                        _setInputPorts(reqInputPorts); // "movedFiles"); // FIXME:
426                                                                                                        // or should this be new
427                                                                                                        // location??
428                                        // _addPorts(this.outputPortList(), reqOutputPorts);
429                                        _setOutputPort("movedFiles");
430                                        try {
431                                                // newPath.setContainer(this);
432                                                hideNewPath.setToken(BooleanToken.FALSE);
433                                                // if (output.getContainer() == null)
434                                                // output.setContainer(this);
435                                        } catch (Exception ex) {
436                                                GraphicalMessageHandler.message(ex.getMessage()
437                                                                + "Could not add input ports in the actor: "
438                                                                + this.getName() + " for command " + cmd);
439                                        }
440                                }
441                                _cmd = _MV;
442                        } else if (cmd.equals("remove")) {
443                                if (flag) {
444                                        _setInputPorts(reqInputPorts); // "parentDir");
445                                        // forwardParentDir.setToken(new BooleanToken(false));
446                                        attributeChanged(forwardParentDir);
447                                }
448                                _cmd = _RM;
449                        } else if (cmd.equals("replicate")) {
450                                if (flag) {
451                                        reqInputPorts.add("newPath");
452                                        // reqOutputPorts.add("output");
453                                        _setInputPorts(reqInputPorts); // "newResource");
454                                        // _addPorts(this.outputPortList(), reqOutputPorts);
455                                        _setOutputPort("newResource");
456                                        try {
457                                                // newPath.setContainer(this);
458                                                hideNewPath.setToken(BooleanToken.FALSE);
459                                                // if (output.getContainer() == null)
460                                                // output.setContainer(this);
461                                        } catch (Exception ex) {
462                                                GraphicalMessageHandler.message(ex.getMessage()
463                                                                + "Could not add input ports in the actor: "
464                                                                + this.getName() + " for command " + cmd);
465                                        }
466                                }
467                                _cmd = _REP;
468                        } else if (cmd.equals("create directory")) {
469                                if (flag) {
470                                        // reqOutputPorts.add("output");
471                                        _setInputPorts(reqInputPorts); // "dirPath");
472                                        // _addPorts(this.outputPortList(), reqOutputPorts);
473                                        _setOutputPort("dirPath");
474                                        /*
475                                         * if (output.getContainer() == null) { try {
476                                         * output.setContainer(this); } catch
477                                         * (NameDuplicationException ex) {
478                                         * GraphicalMessageHandler.message(ex.getMessage() +
479                                         * "Could not add output ports in the actor: " +
480                                         * this.getName() + " for command " + cmd); } }
481                                         */
482                                }
483                                _cmd = _MKDIR;
484                        } else if (cmd.equals("remove directory")) {
485                                if (flag) {
486                                        _setInputPorts(reqInputPorts); // "parentDir");
487                                        // forwardParentDir.setToken(new BooleanToken(false));
488                                        attributeChanged(forwardParentDir);
489                                }
490                                _cmd = _RMDIR;
491                        } else if (cmd.equals("change mode")) {
492                                if (flag) {
493                                        reqInputPorts.add("permission");
494                                        reqInputPorts.add("mdasDomain");
495                                        reqInputPorts.add("userName");
496                                        // reqOutputPorts.add("output");
497                                        _setInputPorts(reqInputPorts); // "exitPath");
498                                        // _addPorts(this.outputPortList(), reqOutputPorts);
499                                        _setOutputPort("exitPath");
500                                        try {
501                                                // permission.setContainer(this);
502                                                hidePermission.setToken(BooleanToken.FALSE);
503                                                // mdasDomain.setContainer(this);
504                                                hideMdasDomain.setToken(BooleanToken.FALSE);
505                                                // userName.setContainer(this);
506                                                hideUserName.setToken(BooleanToken.FALSE);
507
508                                                // if (output.getContainer() == null) {
509                                                // output.setContainer(this);
510                                                // }
511                                        } catch (Exception ex) {
512                                                GraphicalMessageHandler.message(ex.getMessage()
513                                                                + "Could not add input ports in the actor: "
514                                                                + this.getName() + " for command " + cmd);
515                                        }
516                                }
517                                _cmd = _CHMOD;
518                        } else {
519                                // execute proxy command.
520                        }
521                } else if (at == hasTrigger) {
522                        _triggerFlag = ((BooleanToken) hasTrigger.getToken())
523                                        .booleanValue();
524                        _debug("<TRIGGER_FLAG>" + _triggerFlag + "</TRIGGER_FLAG>");
525                        if (_triggerFlag) {
526                                // trigger.setContainer(this);
527                                hideTrigger.setToken(BooleanToken.FALSE);
528                        } else {
529                                List inPortList = this.inputPortList();
530                                Iterator ports = inPortList.iterator();
531                                while (ports.hasNext()) {
532                                        IOPort p = (IOPort) ports.next();
533                                        if (p.isInput()) {
534                                                try {
535                                                        if (p.getName().equals("trigger")) {
536                                                                // p.setContainer(null);
537                                                                hideTrigger.setToken(BooleanToken.TRUE);
538                                                        }
539                                                } catch (Exception e) {
540                                                        GraphicalMessageHandler
541                                                                        .message(e.getMessage()
542                                                                                        + "Could not delete the trigger port in the actor: "
543                                                                                        + this.getName());
544                                                }
545                                        }
546                                }
547                        }
548                } else if (at == outputEachFileSeparately) {
549                        _separate = ((BooleanToken) outputEachFileSeparately.getToken())
550                                        .booleanValue();
551                } else if (at == forwardParentDir) {
552                        _forward = ((BooleanToken) forwardParentDir.getToken())
553                                        .booleanValue();
554                        if ((command.stringValue()).startsWith("remove")) {
555                                if (_forward) {
556                                        _setOutputPort("parentDirs");
557
558                                        /*
559                                         * try { if (output.getContainer() == null)
560                                         * output.setContainer(this); } catch
561                                         * (NameDuplicationException ndex) {
562                                         * GraphicalMessageHandler.message(ndex.getMessage() +
563                                         * "Could not create output port."); }
564                                         */
565                                } else {
566                                        List outPorts = this.outputPortList();
567                                        Iterator ports = outPorts.iterator();
568                                        while (ports.hasNext()) {
569                                                IOPort p = (IOPort) ports.next();
570                                                if (!p.getName().equals("exitCode")) {// this is the
571                                                                                                                                // output port.
572                                                        try {
573                                                                p.setContainer(null);
574                                                        } catch (Exception ndex) {
575                                                                GraphicalMessageHandler.message(ndex
576                                                                                .getMessage()
577                                                                                + "Could not delete output port.");
578                                                        }
579                                                }
580                                        }
581                                }
582                        }
583                } else {
584                        super.attributeChanged(at);
585                }
586        }
587
588        /**
589         * Upload the file to the SRB. If the SRB file path is not specified, upload
590         * to the current working directory. Output the current working directory.
591         * 
592         * @exception IllegalActionException
593         *                If it is thrown if the SRB file cannot be accessed or the
594         *                current directory cannot be broadcasted.
595         */
596        public void fire() throws IllegalActionException {
597                String srcPathStr;
598                String newLoc;
599                SRBFile srcSrbFile;
600                _exitCode = "";
601
602                List inPortList = this.inputPortList();
603                Iterator ports = inPortList.iterator();
604                while (ports.hasNext()) {
605                        IOPort p = (IOPort) ports.next();
606                        if (p.getName().equals("trigger")) {
607                                if (p.getWidth() > 0) {
608                                        for (int i = 0; i < p.getWidth(); i++) {
609                                                p.get(0);
610                                        }
611                                }
612                        }
613                }
614
615                try {
616                        srbFileSystem.getHost();
617                } catch (Exception ex) { // connection was closed.
618                        srbFileSystem = null;
619                        ObjectToken SRBConOT = null;
620                        try { // try to get a new connection in case the previous one has
621                                        // terminated.
622                                SRBConOT = (ObjectToken) SRBFileSystem.get(0);
623                        } catch (NoTokenException ntex) {
624                        }
625                        if (SRBConOT != null) {
626                                srbFileSystem = (SRBFileSystem) SRBConOT.getValue();
627                        }
628                }
629                if (srbFileSystem == null) {
630                        throw new IllegalActionException(this,
631                                        "No SRB connection available in actor " + this.getName()
632                                                        + ".");
633                }
634                ArrayToken atPath = (ArrayToken) path.get(0);
635                Token[] paths = atPath.arrayValue();
636                IOPort output = _getOutputPort();
637
638                switch (_cmd) {
639                case _LS:
640
641                        System.out.println("actor name ==> " + this.getName() + " : Sls");
642                        // TODO: output each row seperately or as a list. output to a
643                        // browser display (add the buttons).
644                        if (paths.length > 1) {
645                                _exitCode += paths.length + " directories were displayed.\n";
646                        }
647                        for (int i = 0; i < paths.length; i++) {
648                                srcPathStr = ((StringToken) paths[i]).stringValue();
649                                srcSrbFile = new SRBFile(srbFileSystem, srcPathStr);
650                                if (srcSrbFile.exists()) {
651                                        if (srcSrbFile.isDirectory()) {
652                                                String[] files = srcSrbFile.list();
653                                                if (files != null && files.length > 0) {
654                                                        if (_separate) {
655                                                                for (int j = 0; j < files.length; j++) {
656                                                                        String absPath = srcSrbFile
657                                                                                        .getAbsolutePath()
658                                                                                        + "/" + files[j];
659                                                                        Token[] _file = new Token[1];
660                                                                        _file[0] = new StringToken(absPath);
661                                                                        output.broadcast(new ArrayToken(_file));
662                                                                }
663                                                        } else {
664                                                                Token _files[] = new Token[files.length];
665                                                                for (int j = 0; j < files.length; j++) {
666                                                                        String absPath = srcSrbFile
667                                                                                        .getAbsolutePath()
668                                                                                        + "/" + files[j];
669                                                                        _files[j] = new StringToken(absPath);
670                                                                }
671                                                                output.broadcast(new ArrayToken(_files));
672                                                        }
673                                                }
674                                        } else { // file is not a directory
675                                                GraphicalMessageHandler.message(srcSrbFile
676                                                                .getAbsolutePath()
677                                                                + " is not a directory.");
678                                        }
679                                } else {
680                                        GraphicalMessageHandler
681                                                        .message("Directory "
682                                                                        + srcSrbFile.getAbsolutePath()
683                                                                        + " does not exist.");
684                                }
685                        }
686                        if (_exitCode.equals("")) {
687                                _exitCode = "success";
688                        }
689                        exitCode.broadcast(new StringToken(_exitCode));
690                        break;
691                case _CP:
692                        System.out.println("actor name ==> " + this.getName() + " : Scp");
693
694                        _cp_mv(srbFileSystem, paths);
695                        break;
696                case _MV:
697                        System.out.println("actor name ==> " + this.getName() + " : Smv");
698
699                        _cp_mv(srbFileSystem, paths);
700                        // TODO: move a whole directory..
701                        break;
702                case _RM:
703                        System.out.println("actor name ==> " + this.getName() + " : Srm");
704
705                        recursive = ((BooleanToken) _r.getToken()).booleanValue();
706                        for (int i = 0; i < paths.length; i++) {
707                                srcPathStr = ((StringToken) paths[i]).stringValue();
708                                SRBFile srbFile = new SRBFile(srbFileSystem, srcPathStr);
709                                String parent = srbFile.getParent();
710                                if (_rm(srbFileSystem, srcPathStr))
711                                        deletedFiles.add(new StringToken(parent));
712                        }
713                        if (_forward) { // currently output parent dirs.
714                                if (deletedFiles.size() > 0) {
715                                        Token _output[] = new Token[deletedFiles.size()];
716                                        deletedFiles.toArray(_output);
717                                        output.broadcast(new ArrayToken(_output));
718                                } else
719                                        System.out.println("no files were removed.");
720                        }
721                        if (_exitCode.equals(""))
722                                _exitCode = "success";
723                        exitCode.broadcast(new StringToken(_exitCode));
724                        // FIXME: what should be returned here?? the files are not
725                        // necessarily from the same dir.
726                        break;
727                case _REP:
728                        System.out.println("actor name ==> " + this.getName() + " : Srep");
729
730                        String newResource = ((StringToken) newPath.get(0)).stringValue();
731                        Token[] reps = new Token[paths.length];
732                        for (int i = 0; i < paths.length; i++) {
733                                srcPathStr = ((StringToken) paths[i]).stringValue();
734                                srcSrbFile = new SRBFile(srbFileSystem, srcPathStr);
735                                try {
736                                        srcSrbFile.replicate(newResource);
737                                        reps[i] = new StringToken(newResource + "/" + srcPathStr);
738                                } catch (IOException e) {
739                                        srbFileSystem = SRBUtil.closeConnection(srbFileSystem);
740                                        srcSrbFile = null;
741                                        GraphicalMessageHandler.message("Could not replicate file "
742                                                        + srcSrbFile.getAbsolutePath() + " to resource "
743                                                        + newResource + ".");
744                                }
745                        }
746                        output.broadcast(new ArrayToken(reps));
747                        exitCode.broadcast(new StringToken("success"));
748                        break;
749                case _MKDIR: // take care of creating several directories at once.
750                        System.out
751                                        .println("actor name ==> " + this.getName() + " : Smkdir");
752
753                        for (int i = 0; i < paths.length; i++) {
754                                srcPathStr = ((StringToken) paths[i]).stringValue();
755                                srcSrbFile = new SRBFile(srbFileSystem, srcPathStr);
756                                System.out.println("file " + srcPathStr + " is a directory ? "
757                                                + srcSrbFile.isDirectory());
758                                if (!srcSrbFile.mkdir()) {
759                                        System.out
760                                                        .println("Directory "
761                                                                        + srcSrbFile.getAbsolutePath()
762                                                                        + " already exists.");
763                                        _exitCode += "Directory " + srcSrbFile.getAbsolutePath()
764                                                        + " already exists.";
765                                }
766                        }
767                        output.broadcast(atPath);
768                        if (_exitCode.equals(""))
769                                _exitCode = "success";
770                        exitCode.broadcast(new StringToken(_exitCode));
771                        break;
772                case _RMDIR:
773                        System.out
774                                        .println("actor name ==> " + this.getName() + " : Srmdir");
775
776                        Token[] fwd = new Token[paths.length];
777                        for (int i = 0; i < paths.length; i++) {
778                                srcPathStr = ((StringToken) paths[i]).stringValue();
779                                srcSrbFile = new SRBFile(srbFileSystem, srcPathStr);
780                                String parent = srcSrbFile.getParent();
781                                if (srcSrbFile.exists())
782                                        if (srcSrbFile.isDirectory()) {
783                                                String[] files = srcSrbFile.list();
784                                                if (files.length > 0) {// directory is not empty!
785                                                        srbFileSystem = SRBUtil
786                                                                        .closeConnection(srbFileSystem);
787                                                        srcSrbFile = null;
788                                                        throw new IllegalActionException(this,
789                                                                        "Cannot remove directory "
790                                                                                        + srcSrbFile.getName()
791                                                                                        + ". Directory "
792                                                                                        + srcSrbFile.getAbsolutePath()
793                                                                                        + " is not empty.");
794                                                } else {
795                                                        srcSrbFile.delete();
796                                                        fwd[i] = new StringToken(parent);
797                                                }
798                                        } else
799                                                GraphicalMessageHandler.message("directory "
800                                                                + srcSrbFile.getAbsolutePath()
801                                                                + " does not exist.");
802                        }
803                        if (_forward)
804                                output.broadcast(new ArrayToken(fwd));
805                        exitCode.broadcast(new StringToken("success"));
806                        // TODO: what should be outputed here? remove non-empty dirs flag.
807                        break;
808                case _CHMOD:
809                        System.out
810                                        .println("actor name ==> " + this.getName() + " : Schmod");
811
812                        String permissionStr = ((StringToken) permission.get(0))
813                                        .stringValue();
814                        String userNameStr = ((StringToken) userName.get(0)).stringValue();
815                        String mdasDomainStr = ((StringToken) mdasDomain.get(0))
816                                        .stringValue();
817                        for (int i = 0; i < paths.length; i++) {
818                                srcPathStr = ((StringToken) paths[i]).stringValue();
819                                srcSrbFile = new SRBFile(srbFileSystem, srcPathStr);
820                                if (srcSrbFile.exists())
821                                        try {
822                                                srcSrbFile.changePermissions(permissionStr,
823                                                                userNameStr, mdasDomainStr);
824                                        } catch (IOException e) {
825                                                srbFileSystem = SRBUtil.closeConnection(srbFileSystem);
826                                                srcSrbFile = null;
827                                                e.printStackTrace();
828                                                throw new IllegalActionException(this,
829                                                                "Could not change premissions for file "
830                                                                                + srcSrbFile.getName() + " in actor "
831                                                                                + this.getName() + ".");
832                                        }
833                                else {
834                                        srbFileSystem = SRBUtil.closeConnection(srbFileSystem);
835                                        GraphicalMessageHandler
836                                                        .message("file " + srcSrbFile.getAbsolutePath()
837                                                                        + " does not exist.");
838                                }
839                        }
840                        output.broadcast(atPath);
841                        exitCode.broadcast(new StringToken("success"));
842                        break;
843                default:
844                        // Execute proxy command???
845                        // System.out.println(command.getExpression() +
846                        // " is not supported");
847                }
848
849        }// end of fire
850
851        /**
852         * Initialize the srb file system to null.
853         */
854        public void initialize() throws IllegalActionException {
855                super.initialize();
856                srbFileSystem = null;
857        }
858
859        /**
860         * Disconnect from SRB.
861         */
862        public void wrapup() {
863                srbFileSystem = SRBUtil.closeConnection(srbFileSystem);
864        }
865
866        // /////////////////////////////////////////////////////////////////
867        // // private methods ////
868
869        /**
870         * Copy or move a file to a new location. Recursively copies/moves non empty
871         * directories
872         * 
873         * @param srbFileSystem
874         *            The srb file system.
875         * @param paths
876         *            Source files paths.
877         * @throws IllegalActionException
878         *             If the new path cannot be consumed.
879         */
880        private void _cp_mv(SRBFileSystem srbFileSystem, Token[] paths)
881                        throws IllegalActionException {
882                // take care of files already exist. exception within rename - returns
883                // boolean.
884                StringToken newPathToken = (StringToken) newPath.get(0);
885                String newLoc = newPathToken.stringValue();
886                SRBFile newFilePath = new SRBFile(srbFileSystem, newLoc);
887                Vector _outputVec = new Vector();
888
889                for (int i = 0; i < paths.length; i++) {
890                        if (!newFilePath.isDirectory() && paths.length > 1) {
891                                // Several files are copied to a single file.
892                                GraphicalMessageHandler
893                                                .message("Trying to copy several files to file "
894                                                                + newFilePath.getAbsolutePath());
895                        }
896                        String srcPathStr = ((StringToken) paths[i]).stringValue();
897                        SRBFile srcSrbFile = new SRBFile(srbFileSystem, srcPathStr);
898                        if (!newFilePath.isDirectory() && srcSrbFile.isDirectory()) {
899                                // Trying to copy a directory to a single file.
900                                GraphicalMessageHandler.message("Trying to copy directory "
901                                                + srcPathStr + " to file "
902                                                + newFilePath.getAbsolutePath());
903                        }
904                        if (srcSrbFile.exists()) {
905                                try {
906                                        String newPathStr = newFilePath.getAbsolutePath(); // if
907                                                                                                                                                // this
908                                                                                                                                                // is a
909                                                                                                                                                // file
910                                                                                                                                                // name.
911                                        if (newFilePath.isDirectory()) { // if this is a directory
912                                                                                                                // add the original file
913                                                                                                                // name.
914                                                newPathStr += "/" + srcSrbFile.getName();
915                                        }
916                                        if (_cmd == _CP) {
917                                                srcSrbFile
918                                                                .copyTo(new SRBFile(srbFileSystem, newPathStr));
919                                        } else if (_cmd == _MV) {
920                                                srcSrbFile.renameTo(new SRBFile(srbFileSystem,
921                                                                newPathStr));
922                                        }
923                                        _outputVec.add(new StringToken(newPathStr));
924                                } catch (IOException e) {
925                                        srbFileSystem = SRBUtil.closeConnection(srbFileSystem);
926                                        srcSrbFile = null;
927                                        GraphicalMessageHandler.message("cannot copy/move file "
928                                                        + srcSrbFile.getAbsolutePath() + " to " + newPath
929                                                        + ".");
930                                }
931                        } else
932                                _exitCode += "file " + srcSrbFile.getAbsolutePath()
933                                                + " does not exist.";
934                }
935                // if files were copied.
936                if (_outputVec.size() > 0) {
937                        Token[] _outputs = new Token[_outputVec.size()];
938                        _outputVec.toArray(_outputs);
939                        IOPort output = _getOutputPort();
940                        output.broadcast(new ArrayToken(_outputs));
941                } else {
942                        _exitCode = "no files were copied/moved";
943                }
944
945                if (_exitCode.equals("")) {
946                        _exitCode = "success";
947                }
948                exitCode.broadcast(new StringToken(_exitCode));
949        }
950
951        /**
952         * Returns the output port if exists.
953         * 
954         * @return output port/null.
955         */
956        private IOPort _getOutputPort() {
957                List outPorts = this.outputPortList();
958                Iterator ports = outPorts.iterator();
959                while (ports.hasNext()) {
960                        IOPort p = (IOPort) ports.next();
961                        if (!p.getName().equals("exitCode")) { // this is the output port.
962                                return p;
963                        }
964                }
965                return null; // no output port exists.
966        }
967
968        /**
969         * Removes a file or a directory. For non-empty directories, recursively
970         * removes the files depending on the -r flag.
971         * 
972         * @param srbFileSystem
973         *            The srb file system.
974         * @param path
975         *            File path.
976         * @throws IllegalActionException
977         *             If the recursive parameter cannot be consumed.
978         */
979        private boolean _rm(SRBFileSystem srbFileSystem, String path)
980                        throws IllegalActionException {
981                SRBFile srbFile = new SRBFile(srbFileSystem, path);
982                if (srbFile.exists()) {
983                        if (srbFile.isDirectory()) {
984                                String files[] = srbFile.list();
985                                if (files.length > 0) {
986                                        if (recursive) {
987                                                // directory is non-empty - recursively deletes files.
988                                                for (int i = 0; i < files.length; i++) {
989                                                        String filePath = srbFile.getAbsolutePath() + "/"
990                                                                        + files[i];
991                                                        _rm(srbFileSystem, filePath);
992                                                }
993                                                // now this dir is empty.
994                                                srbFile.delete();
995                                                return true;
996                                        } else {
997                                                _exitCode += "Directory " + srbFile.getAbsolutePath()
998                                                                + " is not empty\n";
999                                                return false;
1000                                        }
1001                                } else { // this is an empty directory
1002                                        srbFile.delete();
1003                                        return true;
1004                                }
1005                        } else {
1006                                // this is a file.
1007                                srbFile.delete();
1008                                return true;
1009                        }
1010                } else {
1011                        _exitCode += "file " + srbFile.getAbsolutePath()
1012                                        + " does not exist.";
1013                        return false;
1014                }
1015        }
1016
1017        /**
1018         * Set the actor's ports. All commands share the path input port. Add/remove
1019         * input ports specific to the command. Set the output port name specific to
1020         * the command.
1021         * 
1022         * @param outName
1023         *            Set the output port name commandwise.
1024         * @throws IllegalActionException
1025         *             If the output name cannot be set.
1026         */
1027
1028        // private void _setPorts(String outName) throws IllegalActionException {
1029        private void _setInputPorts(List reqInputs) throws IllegalActionException {
1030                List inPortList = this.inputPortList();
1031                _triggerFlag = ((BooleanToken) hasTrigger.getToken()).booleanValue();
1032                reqInputs.add("SRBFileSystem");
1033                reqInputs.add("path");
1034                if (_triggerFlag)
1035                        reqInputs.add("trigger");
1036                // _addPorts(inPortList, reqInputs);
1037                _removePorts(inPortList, reqInputs);
1038        }
1039
1040        /**
1041         * Set the output port container and name.
1042         */
1043        private void _setOutputPort(String outName) throws IllegalActionException {
1044                List outPortList = this.outputPortList();
1045                Iterator ports = outPortList.iterator();
1046                boolean portExists = false; // checking whether the output port exists.
1047                while (ports.hasNext()) {
1048                        TypedIOPort p = (TypedIOPort) ports.next();
1049                        if (!p.getName().equals("exitCode")) { // this is the output port.
1050                                p.setTypeEquals(new ArrayType(BaseType.STRING));
1051                                portExists = true;
1052                                if (!p.getName().equals(outName)) { // this output port doesn't
1053                                                                                                        // have the desired name.
1054                                        try {
1055                                                p.setName(outName);
1056                                        } catch (NameDuplicationException ex) {
1057                                                srbFileSystem = SRBUtil.closeConnection(srbFileSystem);
1058                                                GraphicalMessageHandler.message(ex.getMessage()
1059                                                                + " Actor " + this.getName()
1060                                                                + " already contains a port " + "named "
1061                                                                + outName);
1062                                        }
1063                                }
1064                        }
1065                }
1066                if (!portExists) {
1067                        try {
1068                                TypedIOPort p = new TypedIOPort(this, outName, false, true);
1069                                p.setTypeEquals(new ArrayType(BaseType.STRING));
1070                                new Attribute(p, "_showName");
1071                        } catch (NameDuplicationException ex) {
1072                                srbFileSystem = SRBUtil.closeConnection(srbFileSystem);
1073                                GraphicalMessageHandler.message(ex.getMessage()
1074                                                + " Could not add port " + outName + " to actor "
1075                                                + this.getName());
1076                        }
1077                }
1078        }
1079
1080        /*
1081         * private void _addPorts(List portList, List reqPortsList) { Iterator
1082         * reqPorts = reqPortsList.iterator(); // for each required port, make sure
1083         * it exists in the input ports and if its container is null set it to this.
1084         * while (reqPorts.hasNext()) { boolean exists = false; Iterator ports =
1085         * portList.iterator(); String reqPortName = (String)reqPorts.next(); while
1086         * (ports.hasNext()) { IOPort p = (IOPort) ports.next(); if
1087         * (p.getName().equals(reqPortName) && !p.getContainer().equals(this)) {//
1088         * the required port is within the portList. try { p.setContainer(this); }
1089         * catch (Exception ex) { GraphicalMessageHandler.message(ex.getMessage() +
1090         * "Could not delete input port " + p.getName() + " in actor: " +
1091         * this.getName() + "for command " + command.getExpression()); } } } }
1092         * 
1093         * }
1094         */
1095
1096        /**
1097         * Remove unnecessary port for a specific command.
1098         */
1099        private void _removePorts(List portList, List reqPortsList) {
1100                Iterator ports = portList.iterator();
1101                while (ports.hasNext()) {
1102                        IOPort p = (IOPort) ports.next();
1103                        String portName = p.getName();
1104                        try {
1105                                if (!reqPortsList.contains(portName)) { // this port is not
1106                                                                                                                // required.
1107                                        SingletonParameter sp = (SingletonParameter) singletons
1108                                                        .get(p.getName());
1109                                        // p.setContainer(null); /// input
1110                                        sp.setToken(BooleanToken.TRUE);
1111                                }
1112                        } catch (Exception ex) {
1113                                srbFileSystem = SRBUtil.closeConnection(srbFileSystem);
1114                                GraphicalMessageHandler.message(ex.getMessage()
1115                                                + "Could not delete input port " + portName
1116                                                + " in actor: " + this.getName() + "for command "
1117                                                + command.getExpression());
1118                        }
1119
1120                }
1121
1122        }
1123
1124        // FIXME: TEMPORARILY REMOVED. PROBLEMS WITH CHANGING
1125        // THE OUTPUT PORT NAME WHEN RELOADING A WORKFLOW.
1126        /*
1127         * try { output.setName(outName); } catch (NameDuplicationException ex) {
1128         * GraphicalMessageHandler.message(ex.getMessage() + "Actor " +
1129         * this.getName() + " contains a port " + "named " + outName) ; }
1130         */
1131
1132        // /////////////////////////////////////////////////////////////////
1133        // // private members ////
1134        /** User selected command */
1135        private int _cmd;
1136        String prevCmd = "";
1137        String _exitCode = "";
1138        Vector deletedFiles = new Vector();
1139
1140        /**
1141         * Output separately indicator parameter.
1142         */
1143        private boolean _separate = false;
1144
1145        /**
1146         * Broadcast results indicator parameter.
1147         */
1148        private boolean _forward = false;
1149
1150        /**
1151         * Indicates the existence of an input trigger
1152         */
1153        private boolean _triggerFlag;
1154
1155        /**
1156         * Indicates recursively remove.
1157         */
1158        private boolean recursive = false;
1159
1160        private SRBFileSystem srbFileSystem = null;
1161
1162        // Constants used for more efficient execution.
1163        private static final int _LS = 0;
1164        private static final int _CP = 1;
1165        private static final int _MV = 2;
1166        private static final int _RM = 3;
1167        private static final int _REP = 4;
1168        private static final int _MKDIR = 5;
1169        private static final int _RMDIR = 6;
1170        private static final int _CHMOD = 7;
1171
1172        private Map singletons;
1173}