001/* Interface for parameters that provide web export content.
002
003 Copyright (c) 2011-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 */
028
029package ptolemy.vergil.basic.export.web;
030
031import java.util.List;
032import java.util.Locale;
033
034import ptolemy.actor.CompositeActor;
035import ptolemy.data.expr.StringParameter;
036import ptolemy.kernel.CompositeEntity;
037import ptolemy.kernel.util.IllegalActionException;
038import ptolemy.kernel.util.NameDuplicationException;
039import ptolemy.kernel.util.NamedObj;
040
041///////////////////////////////////////////////////////////////////
042//// DefaultIconScript
043/**
044 * A parameter specifying default JavaScript actions to associate
045 * with icons in model. Putting this attribute into a model causes
046 * the icons of entities, attributes, or both, to be assigned a
047 * default action of type given by <i>eventType</i>, where the
048 * action is defined by the value of this parameter.
049 * This will replace any configuration default that targets
050 * the same event type, includes the same objects, and
051 * targets the same instanceOf possibilities.
052 * <p>
053 * A typical use of this would be to set its string value
054 * to something like "foo(args)" where foo is a JavaScript function
055 * defined in the <i>script</i> parameter.
056 * You can also provide HTML text to insert into the start or
057 * end sections of the container's web page.
058 * </p>
059 *
060 * @author Edward A. Lee
061 * @version $Id$
062 * @since Ptolemy II 10.0
063 * @Pt.ProposedRating Red (cxh)
064 * @Pt.AcceptedRating Red (cxh)
065 */
066public class DefaultIconScript extends IconScript {
067
068    /** Create an instance of this parameter.
069     *  @param container The container.
070     *  @param name The name.
071     *  @exception IllegalActionException If the superclass throws it.
072     *  @exception NameDuplicationException If the superclass throws it.
073     */
074    public DefaultIconScript(NamedObj container, String name)
075            throws IllegalActionException, NameDuplicationException {
076        super(container, name);
077
078        include = new StringParameter(this, "include");
079        include.addChoice("Entities");
080        include.addChoice("Attributes");
081        include.addChoice("All");
082        include.setExpression("Entities");
083
084        instancesOf = new StringParameter(this, "instancesOf");
085    }
086
087    ///////////////////////////////////////////////////////////////////
088    ////                         parameters                        ////
089
090    /** If non-empty (the default), specifies a class name.
091     *  Only entities or attributes (depending on <i>include</i>)
092     *  implementing the specified
093     *  class will be assigned the control defined by this
094     *  DefaultIconScript parameter.
095     */
096    public StringParameter instancesOf;
097
098    /** Specification of whether to provide the default behavior for
099     *  Attributes, Entities, or both. This is either "Entities" (the
100     *  default), "Attributes", or "All".
101     */
102    public StringParameter include;
103
104    ///////////////////////////////////////////////////////////////////
105    ////                         protected methods                 ////
106
107    /** Provide content to the specified web exporter to be
108     *  included in a web page for the container of this object.
109     *  This class provides default content for each object
110     *  as specified by <i>include</i> and <i>instancesOf</i>.
111     *
112     *  @param exporter The web exporter to add content to
113     *  @exception IllegalActionException If a subclass throws it.
114     */
115    @Override
116    protected void _provideAttributes(WebExporter exporter)
117            throws IllegalActionException {
118        WebAttribute webAttribute;
119
120        boolean entities = false, attributes = false;
121        String includeValue = include.stringValue()
122                .toLowerCase(Locale.getDefault());
123        if (includeValue.equals("all")) {
124            entities = true;
125            attributes = true;
126        } else if (includeValue.equals("entities")) {
127            entities = true;
128        } else if (includeValue.equals("attributes")) {
129            attributes = true;
130        }
131        List<NamedObj> objects;
132        String instances = instancesOf.stringValue();
133        NamedObj container = getContainer();
134        if (entities && container instanceof CompositeEntity) {
135            if (instances.trim().equals("")) {
136                objects = ((CompositeEntity) container).entityList();
137            } else {
138                try {
139                    Class restrict = Class.forName(instances);
140                    objects = ((CompositeEntity) container)
141                            .entityList(restrict);
142                } catch (ClassNotFoundException e) {
143                    throw new IllegalActionException(this,
144                            "No such class: " + instances);
145                }
146            }
147            for (NamedObj object : objects) {
148                if (object != null) {
149                    // TODO:  Enable multiple eventTypes
150                    String eventTypeValue = eventType.stringValue();
151                    if (!eventTypeValue.trim().equals("")) {
152                        // Create WebAttribute for event and add to exporter.
153                        // Content should only be added once (onceOnly -> true).
154                        webAttribute = WebAttribute.createWebAttribute(
155                                getContainer(), eventTypeValue + "WebAttribute",
156                                eventTypeValue);
157                        webAttribute.setExpression(stringValue());
158                        exporter.defineAttribute(webAttribute, true);
159
160                        _provideDefaultAttributes(object, exporter);
161                    }
162                }
163            }
164            // If the container is a CompositeActor, then also include
165            // the director, unless specific instances are requested.
166            if ((container instanceof CompositeActor)
167                    && instances.trim().equals("")) {
168                NamedObj director = ((CompositeActor) container).getDirector();
169                if (director != null) {
170                    String eventTypeValue = eventType.stringValue();
171                    // Create WebAttribute for event and add to exporter.
172                    // Content should only be added once (onceOnly -> true).
173                    webAttribute = WebAttribute.createWebAttribute(
174                            getContainer(), eventTypeValue + "WebAttribute",
175                            eventTypeValue);
176                    webAttribute.setExpression(stringValue());
177                    exporter.defineAttribute(webAttribute, true);
178
179                    _provideDefaultAttributes(director, exporter);
180                }
181            }
182        }
183        if (attributes) {
184            if (instances.trim().equals("")) {
185                objects = ((CompositeEntity) container).attributeList();
186            } else {
187                try {
188                    Class restrict = Class.forName(instances);
189                    objects = ((CompositeEntity) container)
190                            .attributeList(restrict);
191                } catch (ClassNotFoundException e) {
192                    throw new IllegalActionException(this,
193                            "No such class: " + instances);
194                }
195            }
196            for (NamedObj object : objects) {
197                // Do not generate events for WebAttributes and WebElements
198                if (object != null && !(object instanceof WebAttribute)
199                        && !(object instanceof WebElement)) {
200                    // TODO:  Enable multiple eventTypes
201                    String eventTypeValue = eventType.stringValue();
202                    if (!eventTypeValue.trim().equals("")) {
203                        // Create WebAttribute for event and add to exporter.
204                        // Content should only be added once (onceOnly -> true).
205                        webAttribute = WebAttribute.createWebAttribute(
206                                getContainer(), eventTypeValue + "WebAttribute",
207                                eventTypeValue);
208                        webAttribute.setExpression(stringValue());
209                        exporter.defineAttribute(webAttribute, true);
210
211                        _provideDefaultAttributes(object, exporter);
212                    }
213                }
214            }
215        }
216    }
217
218    /** Return attributes for default events, e.g. onmouseover().  If an
219     *  attribute is already defined for this event, do nothing.
220     *  Returns null in this class.  Derived classes should override.
221     *
222     * @param exporter The WebExporter to add content to
223     * @param object  The NamedObj to generate default events for
224     * @exception IllegalActionException If there is a problem creating the content
225     * or if there is a name duplication with the created attributes
226     */
227    protected void _provideDefaultAttributes(NamedObj object,
228            WebExporter exporter) throws IllegalActionException {
229    }
230
231}