001/*
002 * Copyright (c) 2017 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2017-07-14 00:01:00 +0000 (Fri, 14 Jul 2017) $' 
007 * '$Revision: 34590 $'
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 */
029package org.kepler.util;
030
031import java.io.File;
032import java.util.HashMap;
033import java.util.Iterator;
034import java.util.Map;
035
036import org.apache.commons.configuration.ConfigurationException;
037import org.apache.commons.configuration.PropertiesConfiguration;
038
039import ptolemy.actor.CompositeActor;
040import ptolemy.actor.Director;
041import ptolemy.kernel.util.Attribute;
042import ptolemy.kernel.util.IllegalActionException;
043import ptolemy.kernel.util.NamedObj;
044import ptolemy.kernel.util.Settable;
045import ptolemy.moml.MoMLChangeRequest;
046
047/** A utility class to parse workflows and related files.
048 * 
049 *  @author Daniel Crawl
050 *  @version $Id: ParseWorkflowUtil.java 34590 2017-07-14 00:01:00Z crawl $
051 */
052public class ParseWorkflowUtil {
053    
054    /**
055     * Read a file containing name value pairs of parameters.
056     * 
057     * @return a map of parameter name values.
058     */
059    public static Map<String, String> parseParameterFile(String fileStr) throws IllegalActionException {
060
061        Map<String, String> parameters = new HashMap<String, String>();
062
063        System.out.println("Reading parameters file " + fileStr);
064
065        File file = new File(fileStr);
066        if (!file.exists()) {
067            throw new IllegalActionException("Parameter file does not exist: " + file.getAbsolutePath());
068        }
069        if (!file.isFile()) {
070            throw new IllegalActionException("Parameter file is a directory.");
071        }
072
073        PropertiesConfiguration config = new PropertiesConfiguration();
074        try {
075            config.load(file);
076        } catch (ConfigurationException e) {
077            throw new IllegalActionException("Error parsing " + file + ": " + e.getMessage());
078        }
079
080        Iterator<String> iterator = config.getKeys();
081        while (iterator.hasNext()) {
082            String key = iterator.next();
083            String val = config.getString(key);
084            // remove any surrounding double-quotes
085            if (val.startsWith("\"") && val.endsWith("\"")) {
086                val = val.substring(1, val.length() - 1);
087            }
088            // System.out.println("read key val: " + key + " " + val);
089            parameters.put(key, val);
090        }
091
092        return parameters;
093    }
094        
095    /** Set a parameter value in a workflow.
096     *  @param model The workflow.
097     *  @param name The name of the parameter.
098     *  @param value The value of the parameter.
099     *  @return True if the workflow contains a parameter matching the name.
100     */
101    public static boolean setModelParameter(NamedObj model, String name, String value) {
102        
103        boolean match = false;
104        
105        // System.out.println("model = " + model.getFullName());
106        Attribute attribute = model.getAttribute(name);
107
108        if (attribute instanceof Settable) {
109            match = true;
110
111            // Use a MoMLChangeRequest so that visual rendition (if
112            // any) is updated and listeners are notified.
113            String moml = "<property name=\"" + name + "\" value=\"" + value + "\"/>";
114            MoMLChangeRequest request = new MoMLChangeRequest(model, model, moml);
115            model.requestChange(request);            
116            //System.out.println("set " + name + " to " + value);
117        }
118
119        if (model instanceof CompositeActor) {
120            Director director = ((CompositeActor) model).getDirector();
121
122            if (director != null) {
123                attribute = director.getAttribute(name);
124
125                if (attribute instanceof Settable) {
126                    match = true;
127
128                    // Use a MoMLChangeRequest so that visual
129                    // rendition (if
130                    // any) is updated and listeners are notified.
131                    String moml = "<property name=\"" + name + "\" value=\"" + value + "\"/>";
132                    MoMLChangeRequest request = new MoMLChangeRequest(model, director, moml);
133                    director.requestChange(request);
134                }
135            }
136        }
137        
138        return match;
139    }
140    
141    /** Set parameters in a workflow from a configuration file. */
142    public static void setParametersFromFile(NamedObj model, String parameterFileStr) throws IllegalActionException {
143        
144        Map<String,String> parameters = parseParameterFile(parameterFileStr);
145        
146        for(Map.Entry<String, String> parameterEntry : parameters.entrySet()) {
147            if(!setModelParameter(model, parameterEntry.getKey(), parameterEntry.getValue())) {
148                throw new IllegalActionException("Parameter " +
149                    parameterEntry.getKey() +
150                    " not in workflow.");
151            }
152        }        
153    }
154}