001/* 002 * Copyright (c) 2004-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.kepler.actor.ssh; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.kepler.ssh.ExecException; 035import org.kepler.ssh.ExecFactory; 036import org.kepler.ssh.ExecInterface; 037 038import ptolemy.actor.TypedAtomicActor; 039import ptolemy.actor.TypedIOPort; 040import ptolemy.actor.parameters.PortParameter; 041import ptolemy.data.BooleanToken; 042import ptolemy.data.StringToken; 043import ptolemy.data.expr.Parameter; 044import ptolemy.data.type.BaseType; 045import ptolemy.kernel.CompositeEntity; 046import ptolemy.kernel.util.IllegalActionException; 047import ptolemy.kernel.util.NameDuplicationException; 048 049////////////////////////////////////////////////////////////////////////// 050//// DirectoryCreator 051 052/** 053 * <p> 054 * Actor for creating a local/remote directory. 055 * </p> 056 * 057 * <p> 058 * The input should define: 059 * <ul> 060 * <li>the target machine, either "" or "local" to denote the local machine to 061 * be used by Java I/O commands, OR "[user@]host[:port]" to denote a remote 062 * machine to be used by an ssh connection.</li> 063 * <li>the directory to be created (given as String).</li> 064 * </ul> 065 * 066 * </p> 067 * <p> 068 * A relative path is relative to the home directory in case of remote 069 * operations and relative to the current directory in case of local operations. 070 * 071 * </p> 072 * <p> 073 * The actor creates the directory and emits 'true' on the 'succ' port if it is 074 * successful. On the 'error' port, an empty string is emitted, so that this 075 * actor can be used under SDF. 076 * 077 * </p> 078 * <p> 079 * On error, 'false' is emitted on 'succ' and the error output of the commands 080 * on the 'error' port. 081 * 082 * </p> 083 * <p> 084 * If the 'parent' flag is set the operation is considered to be successful even 085 * if the directory already exists. Intermediate directories in the provided 086 * path will be created if necessary (as the 'mkdir -p' unix command and the 087 * File.mkdirs() method work). 088 * 089 * </p> 090 * <p> 091 * This actor uses org.kepler.ssh.SshExec class to create a remote directory or 092 * org.kepler.ssh.LocalExec class to create a local directory.In the first case, 093 * the unix command "mkdir" or "mkdir -p" is used, depending on the parent flag. 094 * In the latter case, File.mkdir() or File.mkdirs() method is used to create 095 * the directory. 096 * </p> 097 * 098 * @author Norbert Podhorszki 099 * @version $Id: DirectoryCreator.java 24234 2010-05-06 05:21:26Z welker $ 100 * @since Ptolemy II 5.0.1 101 */ 102public class DirectoryCreator extends TypedAtomicActor { 103 /** 104 * Construct an actor with the given container and name. 105 * 106 * @param container 107 * The container. 108 * @param name 109 * The name of this actor. 110 * @exception IllegalActionException 111 * If the actor cannot be contained by the proposed 112 * container. 113 * @exception NameDuplicationException 114 * If the container already has an actor with this name. 115 */ 116 public DirectoryCreator(CompositeEntity container, String name) 117 throws NameDuplicationException, IllegalActionException { 118 super(container, name); 119 120 // Uncomment the next line to see debugging statements 121 // addDebugListener(new ptolemy.kernel.util.StreamListener()); 122 123 // target selects the machine where the directory is to be accessed 124 target = new PortParameter(this, "target", new StringToken( 125 "[ local | [user@]host[:port] ]")); 126 new Parameter(target.getPort(), "_showName", BooleanToken.TRUE); 127 128 // dir is the path to the directory to be listed on the target machine 129 dir = new PortParameter(this, "dir", new StringToken("/path/to/dir")); 130 new Parameter(dir.getPort(), "_showName", BooleanToken.TRUE); 131 132 // parent parameter 133 parent = new Parameter(this, "parent", new BooleanToken(true)); 134 parent.setTypeEquals(BaseType.BOOLEAN); 135 136 /* 137 * Output ports 138 */ 139 140 succ = new TypedIOPort(this, "succ", false, true); 141 succ.setTypeEquals(BaseType.BOOLEAN); 142 new Parameter(succ, "_showName", BooleanToken.TRUE); 143 144 error = new TypedIOPort(this, "error", false, true); 145 error.setTypeEquals(BaseType.STRING); 146 new Parameter(error, "_showName", BooleanToken.TRUE); 147 148 _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" " 149 + "width=\"75\" height=\"50\" style=\"fill:blue\"/>\n" 150 + "<text x=\"5\" y=\"30\"" 151 + "style=\"font-size:14; fill:yellow; font-family:SansSerif\">" 152 + "SshExec</text>\n" + "</svg>\n"); 153 154 } 155 156 /*********************************************************** 157 * ports and parameters 158 */ 159 160 /** 161 * The machine to be used at job submission. It should be null, "" or 162 * "local" for the local machine or [user@]host[:port] to denote a remote 163 * machine accessible with ssh. 164 * 165 * This parameter is read once at initialize. 166 */ 167 public PortParameter target; 168 169 /** 170 * The path to the directory to be read on the target machines. This 171 * parameter is read once at initialize. 172 */ 173 public PortParameter dir; 174 175 /** 176 * Specifying whether parent directories should be created recursively if 177 * necessary. 178 */ 179 public Parameter parent; 180 181 /** 182 * The flag of successful operation. It is a port of type Boolean token. 183 */ 184 public TypedIOPort succ; 185 186 /** 187 * The string representation of all the errors that happened during the 188 * execution of the actor, if there are any, otherwise an empty string. A 189 * port of type String token. 190 */ 191 public TypedIOPort error; 192 193 /*********************************************************** 194 * public methods 195 */ 196 197 /** 198 * initialize() runs once before first exec 199 * 200 * @exception IllegalActionException 201 * If the parent class throws it. 202 */ 203 public void initialize() throws IllegalActionException { 204 super.initialize(); 205 } 206 207 /** 208 * fire 209 * 210 * @exception IllegalActionException 211 */ 212 public void fire() throws IllegalActionException { 213 super.fire(); 214 215 // update PortParameters 216 target.update(); 217 dir.update(); 218 219 _target = ((StringToken) target.getToken()).stringValue().trim(); 220 _dir = ((StringToken) dir.getToken()).stringValue().trim(); 221 _parent = ((BooleanToken) parent.getToken()).booleanValue(); 222 223 if (isDebugging) 224 log.debug("Create Directory: " + "target = " + _target + "; dir = " 225 + _dir + "; parent = " + _parent); 226 227 228 // execute the directory create command 229 boolean _succ; 230 String _error; 231 try { 232 233 // get the actual execution object (local or remote) 234 ExecInterface execObj = ExecFactory.getExecObject(_target); 235 _succ = execObj.createDir(_dir, _parent); 236 237 if (isDebugging) 238 log 239 .debug(_succ ? "Directory created: " + _target + ":" 240 + _dir : "Directory operation failed: " 241 + _target + ":" + _dir); 242 _error = new String(""); 243 244 }catch (ExecException ex) { 245 _error = new String( 246 "DirectoryCreator error when creating directory " + _target 247 + ":" + _dir + ".\n" + ex); 248 _succ = false; 249 log.error(_error); 250 } 251 252 succ.send(0, new BooleanToken(_succ)); 253 error.send(0, new StringToken(_error)); 254 255 } 256 257 private String _target; 258 private String _dir; 259 private boolean _parent; 260 261 private static final Log log = LogFactory.getLog(DirectoryCreator.class 262 .getName()); 263 private static final boolean isDebugging = log.isDebugEnabled(); 264 265}