001/*
002 * Copyright (c) 2005-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2018-07-07 23:43:34 +0000 (Sat, 07 Jul 2018) $' 
007 * '$Revision: 34701 $'
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;
031
032import java.io.File;
033import java.io.IOException;
034import java.util.Random;
035import java.util.UUID;
036
037import ptolemy.actor.TypedIOPort;
038import ptolemy.actor.lib.LimitedFiringSource;
039import ptolemy.actor.parameters.PortParameter;
040import ptolemy.data.expr.Parameter;
041import ptolemy.data.BooleanToken;
042import ptolemy.data.StringToken;
043import ptolemy.data.type.BaseType;
044import ptolemy.kernel.CompositeEntity;
045import ptolemy.kernel.util.IllegalActionException;
046import ptolemy.kernel.util.NameDuplicationException;
047
048//////////////////////////////////////////////////////////////////////////
049//// RandomDirectoryMaker
050
051/**
052 * This actor creates a new directory. The corresponding path is given out.
053 * 
054 * @author Jianwu Wang
055 * @version $Id: RandomDirectoryMaker.java 34701 2018-07-07 23:43:34Z crawl $
056 */
057public class RandomDirectoryMaker extends LimitedFiringSource {
058
059    /**
060     * Construct a RandomDirectoryMaker with the given container and name.
061     * 
062     * @param container
063     *            The container.
064     * @param name
065     *            The name of this actor.
066     * @exception IllegalActionException
067     *                If the entity cannot be contained by the proposed
068     *                container.
069     * @exception NameDuplicationException
070     *                If the container already has an actor with this name.
071     */
072    public RandomDirectoryMaker(CompositeEntity container, String name)
073            throws NameDuplicationException, IllegalActionException {
074        super(container, name);
075
076        path = new TypedIOPort(this, "path", false, true);
077        path.setTypeEquals(BaseType.STRING);
078
079        parentDir = new PortParameter(this, "parent directory name");
080        parentDir.setStringMode(true);
081        parentDir.getPort().setTypeEquals(BaseType.STRING);
082
083        useUUID = new Parameter(this, "useUUID");
084        useUUID.setTypeEquals(BaseType.BOOLEAN);
085        useUUID.setToken(BooleanToken.FALSE);
086
087        _attachText("_iconDescription", "<svg>\n" + "<rect x=\"-25\" y=\"-20\" "
088                + "width=\"50\" height=\"40\" " + "style=\"fill:white\"/>\n"
089                + "<polygon points=\"-15,-10 -12,-10 -8,-14 -1,-14 3,-10"
090                + " 15,-10 15,10, -15,10\" " + "style=\"fill:red\"/>\n"
091                + "</svg>\n");
092    }
093
094    // /////////////////////////////////////////////////////////////////
095    // // ports and parameters ////
096
097    /**
098     * The output port, which contains the new directory path.
099     */
100    public TypedIOPort path = null;
101    /**
102     * The parameter, which is a string with the directory name.
103     */
104    public PortParameter parentDir = null;
105
106    /** If true, use UUIDs for the random directory name. Otherwise,
107     use integers.
108    */
109    public Parameter useUUID;
110
111    // /////////////////////////////////////////////////////////////////
112    // // public methods ////
113
114    /**
115     * Create the new directory.
116     * 
117     * @exception IllegalActionException
118     *                If there's no director or if directory making does not
119     *                work.
120     */
121    @Override
122    public void fire() throws IllegalActionException {
123        super.fire();
124        parentDir.update();
125        String dirName = ((StringToken)parentDir.getToken()).stringValue();
126        String childDirName = null;
127        if (dirName.length() > 0) {
128            File dir = new File(dirName);
129            File childDir = null;
130            if (dir.exists() && !dir.isDirectory()) {
131                throw new IllegalActionException(this, dir
132                        + " exists and is not a directory.");
133            }
134            if(dir.exists() && !dir.canWrite()) {
135                throw new IllegalActionException(this, dir
136                        + " exists but doesn't have write perssion.");
137            }
138            else
139            {
140                boolean mkdirsSuccess = false;
141                if(((BooleanToken)useUUID.getToken()).booleanValue()) {
142                    while(!mkdirsSuccess) {
143                        childDir = new File(dir, UUID.randomUUID().toString());
144                        if(!childDir.exists()) {
145                            mkdirsSuccess = childDir.mkdirs();
146                        }
147                    }
148                } else {
149                    Random ran = new Random();
150                    do
151                    {
152                        int randomInt = ran.nextInt();
153                        if (randomInt < 0) {
154                            randomInt = 0 - randomInt;
155                        }
156                        childDir = new File(dir, new Integer (randomInt).toString());
157                        if (!childDir.exists()) {
158                            mkdirsSuccess = childDir.mkdirs();
159                        }
160                    }   
161                    while (!mkdirsSuccess);
162                }
163            }
164            try {
165                childDirName = childDir.getCanonicalPath();
166            } catch (IOException ex) {
167                _debug("Cannot get directory path.");
168                throw new IllegalActionException(this, "Cannot get directory path of " + childDir);
169            }
170        }
171        path.broadcast(new StringToken(childDirName));
172    }
173}