001/* A DDP pattern composite actor with two inputs.
002 *  
003 * Copyright (c) 2011-2012 The Regents of the University of California.
004 * All rights reserved.
005 *
006 * '$Author: crawl $'
007 * '$Date: 2014-05-09 21:10:24 +0000 (Fri, 09 May 2014) $' 
008 * '$Revision: 32714 $'
009 * 
010 * Permission is hereby granted, without written agreement and without
011 * license or royalty fees, to use, copy, modify, and distribute this
012 * software and its documentation for any purpose, provided that the above
013 * copyright notice and the following two paragraphs appear in all copies
014 * of this software.
015 *
016 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
017 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
018 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
019 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
020 * SUCH DAMAGE.
021 *
022 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
023 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
025 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
026 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
027 * ENHANCEMENTS, OR MODIFICATIONS.
028 *
029 */
030package org.kepler.ddp.actor.pattern;
031
032import ptolemy.actor.TypedIOPort;
033import ptolemy.data.expr.StringParameter;
034import ptolemy.kernel.CompositeEntity;
035import ptolemy.kernel.util.Attribute;
036import ptolemy.kernel.util.IllegalActionException;
037import ptolemy.kernel.util.NameDuplicationException;
038import ptolemy.kernel.util.Workspace;
039
040/** A DDP pattern composite actor with two inputs.
041 * 
042 *  @author Daniel Crawl
043 *  @version $Id: DualInputPatternActor.java 32714 2014-05-09 21:10:24Z crawl $
044 */
045public class DualInputPatternActor extends SingleInputPatternActor {
046
047    /** Construct a new DualInputPatternActor in a workspace. */
048    public DualInputPatternActor(Workspace workspace) {
049        super(workspace);
050    }
051
052    /** Construct a new DualInputPatternActor in a container with a given name. */
053    public DualInputPatternActor(CompositeEntity container, String name)
054            throws IllegalActionException, NameDuplicationException {
055        super(container, name);
056
057        in2 = new TypedIOPort(this, "in2", true, false);
058        in2.setTypeAtMost(Types.keyValueArrayType);
059        
060        in2KeyValueTypes = new StringParameter(this, "in2KeyValueTypes");
061        for(String type : _commonKeyValueTypes) {
062            in2KeyValueTypes.addChoice(type);
063        }
064
065    }
066    
067    /** React to a change in an attribute. */
068    @Override
069    public void attributeChanged(Attribute attribute) throws IllegalActionException {
070        
071        if(attribute == in2KeyValueTypes) {
072            in2.typeConstraints().clear();
073            String typesStr = in2KeyValueTypes.stringValue();
074            if(typesStr.isEmpty()) {
075                in2.setTypeAtMost(Types.keyValueArrayType);
076            } else {
077                in2.setTypeAtMost(Types.getKeyValueType(in2KeyValueTypes, typesStr));
078            }
079        } else {
080            super.attributeChanged(attribute);
081        }
082    }
083    
084    /** Override the parent class to check that parameter values are correctly set. */
085    @Override
086    public void preinitialize() throws IllegalActionException {
087        
088        super.preinitialize();
089        
090        // verify that execution class is set iff the key value types are set
091        
092        // NOTE: only perform these checks if we are not the top level model,
093        // i.e., not the model running as a task by the DDP engine.
094        if(toplevel() != this) {
095            
096            final boolean executionClassSet = !_executionClassName.isEmpty();
097            final boolean executionCodeSet = (_executionCodeType != null && !_executionCodeType.isEmpty());
098
099            String in2Str = in2KeyValueTypes.stringValue();
100            boolean in2Set = false;
101            if(in2Str != null && !in2Str.isEmpty()) {
102                in2Set = true;
103            }
104                        
105            if((executionClassSet || executionCodeSet) && !in2Set) {
106                throw new IllegalActionException(this, "The execution class or code is set, " +
107                        "but not in2KeyValueTypes. If you specify the execution class or " +
108                        "code, set in2KeyValueTypes.");
109            }
110            
111            if(!executionClassSet && !executionCodeSet && in2Set) {
112                throw new IllegalActionException(this, "The execution class and code is not " +
113                        "set, but in2KeyValueTypes is set. If you do not specify the " +
114                        "execution class or code, clear in2KeyValueTypes.");
115            }
116
117        }
118        
119    }    
120    
121    /** Second data input. */
122    public TypedIOPort in2;
123
124    /** The input 2 key value types. This parameter should only be set
125     *  when executionClass is specified.
126     */
127    public StringParameter in2KeyValueTypes;
128
129}