001/* A component with functionality given in Java.
002
003 Copyright (c) 1997-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.component;
029
030import ptolemy.data.TupleToken;
031import ptolemy.kernel.ComponentEntity;
032import ptolemy.kernel.CompositeEntity;
033import ptolemy.kernel.Port;
034import ptolemy.kernel.util.IllegalActionException;
035import ptolemy.kernel.util.NameDuplicationException;
036
037///////////////////////////////////////////////////////////////////
038//// AtomicComponent
039
040/**
041 A component with functionality given in Java. The functionality can
042 be given in the {@link #run()} method or by the
043 {@link MethodCallPort#call(TupleToken)} method of contained ports
044 that are providers.
045
046 @author Yang Zhao
047 @version $Id$
048 @since Ptolemy II 11.0
049 @Pt.ProposedRating yellow (ellen_zh)
050 @Pt.AcceptedRating red (cxh)
051 */
052public class AtomicComponent extends ComponentEntity implements Component {
053    /** Construct an entity with the given name contained by the specified
054     *  entity. The container argument must not be null, or a
055     *  NullPointerException will be thrown.  This entity will use the
056     *  workspace of the container for synchronization and version counts.
057     *  If the name argument is null, then the name is set to the empty string.
058     *  Increment the version of the workspace.
059     *  This constructor write-synchronizes on the workspace.
060     *  @param container The container entity.
061     *  @param name The name of the entity.
062     *  @exception IllegalActionException If the entity cannot be contained
063     *   by the proposed container.
064     *  @exception NameDuplicationException If the name coincides with
065     *   an entity already in the container.
066     */
067    public AtomicComponent(CompositeEntity container, String name)
068            throws IllegalActionException, NameDuplicationException {
069        super(container, name);
070        setContainer(container);
071        _addIcon();
072    }
073
074    ///////////////////////////////////////////////////////////////////
075    ////                         public methods                    ////
076
077    /** Initialize the component, which in this base class means
078     *  doing nothing and returning immediately.  This is invoked once after
079     *  preinitialize() and again whenever the component needs
080     *  to be reinitialized.
081     *  @exception IllegalActionException If initialization
082     *   cannot be completed (not thrown in this base class).
083     */
084    @Override
085    public void initialize() throws IllegalActionException {
086    }
087
088    /** Create a new port with the specified name.
089     *  The container of the port is set to this entity.
090     *  This overrides the base class to create an instance of MethodCallPort.
091     *  Derived classes may override this to further constrain the ports.
092     *  This method is write-synchronized on the workspace and increments
093     *  its version number.
094     *  @param name The new port name.
095     *  @return The new port
096     *  @exception IllegalActionException If the argument is null.
097     *  @exception NameDuplicationException If this entity already has a
098     *   port with the specified name.
099     */
100    @Override
101    public Port newPort(String name)
102            throws IllegalActionException, NameDuplicationException {
103        try {
104            _workspace.getWriteAccess();
105
106            Port port = new MethodCallPort(this, name);
107            return port;
108        } finally {
109            _workspace.doneWriting();
110        }
111    }
112
113    /** Preinitialize the component, which in this base class means doing
114     *  nothing and returning immediately. This is invoked exactly
115     *  once per execution of a model, before any other methods
116     *  in this interface are invoked.
117     *  @exception IllegalActionException If preinitialization
118     *   cannot be completed (not thrown in this base class).
119     */
120    @Override
121    public void preinitialize() throws IllegalActionException {
122    }
123
124    /** Execute the component, which in this base class means doing
125     *  nothing and returning immediately.
126     *  This is invoked after preinitialize()
127     *  and initialize(), and may be invoked repeatedly.
128     *  @exception IllegalActionException If the run cannot be completed
129     *   (not thrown in this base class).
130     */
131    @Override
132    public void run() throws IllegalActionException {
133    }
134
135    /** Wrap up an execution, which in this base class means doing
136     *  nothing and returning immediately. This method is invoked
137     *  exactly once per execution of a model. It finalizes
138     *  an execution, typically
139     *  closing files, displaying final results, etc. If any other
140     *  method from this interface is invoked after this, it must
141     *  begin with preinitialize().
142     *  @exception IllegalActionException If wrapup fails.
143     */
144    @Override
145    public void wrapup() throws IllegalActionException {
146    }
147
148    ///////////////////////////////////////////////////////////////////
149    ////                         protected methods                 ////
150
151    /** Add a port to this entity. This overrides the base class to
152     *  throw an exception if the added port is not an instance of
153     *  MethodCallPort.  This method should not be used
154     *  directly.  Call the setContainer() method of the port instead.
155     *  This method does not set
156     *  the container of the port to point to this entity.
157     *  It assumes that the port is in the same workspace as this
158     *  entity, but does not check.  The caller should check.
159     *  Derived classes may override this method to further constrain to
160     *  a subclass of MethodCallPort.
161     *  This method is <i>not</i> synchronized on the workspace, so the
162     *  caller should be.
163     *  @param port The port to add to this entity.
164     *  @exception IllegalActionException If the port class is not
165     *   acceptable to this entity, or the port has no name.
166     *  @exception NameDuplicationException If the port name collides with a
167     *   name already in the entity.
168     */
169    @Override
170    protected void _addPort(Port port)
171            throws IllegalActionException, NameDuplicationException {
172        if (!(port instanceof MethodCallPort)) {
173            throw new IllegalActionException(this, port,
174                    "Incompatible port class for this entity.");
175        }
176
177        super._addPort(port);
178    }
179
180    ///////////////////////////////////////////////////////////////////
181    ////                         private methods                   ////
182    private void _addIcon() {
183        _attachText("_iconDescription",
184                "<svg>\n" + "<rect x=\"-30\" y=\"-20\" width=\"60\" "
185                        + "height=\"40\" style=\"fill:white\"/>\n"
186                        + "<polygon points=\"-20,-10 20,0 -20,10\" "
187                        + "style=\"fill:blue\"/>\n" + "</svg>\n");
188    }
189}