/* * $RCSfile: TimedElementNode.java,v $ * * Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */ package com.sun.perseus.model; import com.sun.perseus.util.SVGConstants; import org.w3c.dom.DOMException; import org.w3c.dom.svg.SVGAnimationElement; import com.sun.perseus.j2d.RenderGraphics; /** * <code>TimedElementNode</code> models <code>ModelNodes</code which * represent Timed Elements. * * * @version $Id: TimedElementNode.java,v 1.6 2006/07/13 00:55:58 st125089 Exp $ */ public class TimedElementNode extends ElementNode implements SVGAnimationElement { /** * The timing support is added by compositing rather than inheritance * because Java only allows single inheritance. */ protected TimedElementSupport timedElementSupport; /** * The timed element's local name. */ protected String localName; /** * Builds a new timed element that belongs to the given * document. This <code>TimedElementNode</code> will belong * to the <code>DocumentNode</code>'s time container. * * @param ownerDocument the document this node belongs to. * @param localName the element's local name * @throws IllegalArgumentException if the input ownerDocument is null */ public TimedElementNode(final DocumentNode ownerDocument, final String localName) { this(ownerDocument, new TimedElementSupport(), localName); } /** * Builds a new timed element that belongs to the given * document. This <code>TimedElementNode</code> will belong * to the <code>DocumentNode</code>'s time container. * * @param ownerDocument the document this node belongs to. * @throws IllegalArgumentException if the input ownerDocument is null */ public TimedElementNode(final DocumentNode ownerDocument) { this(ownerDocument, new TimedElementSupport()); } /** * Constructor used by derived classes. * * @param ownerDocument the document this node belongs to. * @param timedElementSupport the associated * <code>TimedElementSupport</code>. * @throws IllegalArgumentException if the input ownerDocument is null. */ protected TimedElementNode(final DocumentNode ownerDocument, final TimedElementSupport timedElementSupport) { this(ownerDocument, timedElementSupport, // <!> IMPL NOTE : DO THIS WHILE THE REST OF THE ANIMATION // IMPLEMENTATION IS PENDING. SVGConstants.SVG_SET_TAG); } /** * Constructor used by derived classes. * * @param ownerDocument the document this node belongs to. * @param timedElementSupport the associated * <code>TimedElementSupport</code>. * @param localName the element's local name. Should not be null. * @throws IllegalArgumentException if the input ownerDocument is null * or if the input timedElementSupport is null. */ protected TimedElementNode(final DocumentNode ownerDocument, final TimedElementSupport timedElementSupport, final String localName) { super(ownerDocument); if (timedElementSupport == null) { throw new IllegalArgumentException(); } if (localName == null) { throw new IllegalArgumentException(); } this.timedElementSupport = timedElementSupport; this.localName = localName; timedElementSupport.animationElement = this; } /** * When a TimedElementNode is hooked into the document tree, it needs * to register with the closest ancestor TimeContainerNode it can * find. If none, it must register with the root time container. */ void nodeHookedInDocumentTree() { super.nodeHookedInDocumentTree(); ModelNode p = parent; while (p != ownerDocument && p != null) { if (p instanceof TimeContainerNode) { timedElementSupport.setTimeContainer (((TimeContainerNode) p).timeContainerSupport); break; } p = p.parent; } if (p == ownerDocument) { timedElementSupport.setTimeContainer (ownerDocument.timeContainerRootSupport); } } /** * When a TimedElementNode is unhooked from the document tree, it * needs to unregister from its TimeContainer node. Extentions, such * as Animation, may have to perform additional operations, such as * removing themselves from TraitAnim. */ void nodeUnhookedFromDocumentTree() { timedElementSupport.reset(); timedElementSupport.setTimeContainer(null); } /** * @return the animation tag name passed at construction time. */ public String getLocalName() { return localName; } /** * The default value for the begin attribute is '0s'. * * @return an array of trait default values, used if this element * requires that the default trait value be explicitly * set through a setTrait call. This happens, for example, * with the begin trait value on animation elements. */ public String[][] getDefaultTraits() { return new String[][] { {SVGConstants.SVG_BEGIN_ATTRIBUTE, "0s"} }; } /** * Used by <code>DocumentNode</code> to create a new instance from * a prototype <code>TimedElementNode</code>. * * @param doc the <code>DocumentNode</code> for which a new node is * should be created. * @return a new <code>TimedElementNode</code> for the requested document. */ public ElementNode newInstance(final DocumentNode doc) { return new TimedElementNode(doc, new TimedElementSupport(), localName); } /** * @return this node's <code>TimedElementSupport</code> */ public TimedElementSupport getTimedElementSupport() { return timedElementSupport; } /** * */ public void beginElementAt(float offset) { timedElementSupport.beginAt((long) (offset * 1000)); } /** * Creates a begin instance time for the current time. */ public void beginElement() { timedElementSupport.beginAt(0); } /** * */ public void endElementAt(float offset) { timedElementSupport.endAt((long) (offset * 1000)); } /** * Creates an end instance time for the current time. */ public void endElement() { timedElementSupport.endAt(0); } /** * Pauses the element. If the element is already paused, this method has no * effect. See the SMIL 2 specification for a description of <a * href="http://www.w3.org/TR/2001/REC-smil20-20010807/smil20.html#smil-timing-Timing-PausedElementsAndActiveDur">pausing * elements</a>. */ public void pauseElement() { throw new Error("NOT IMPLEMENTED"); } /** * Unpauses the element if it was paused. If the element was not paused, * this method has no effect. See the SMIL 2 specification for a description * of <a * href="http://www.w3.org/TR/2001/REC-smil20-20010807/smil20.html#smil-timing-Timing-PausedElementsAndActiveDur">pausing * elements</a>. */ public void unpauseElement() { throw new Error("NOT IMPLEMENTED"); } /** * @return true if the element is currently paused, false otherwise. See the * SMIL 2 specification for a description of <a * href="http://www.w3.org/TR/2001/REC-smil20-20010807/smil20.html#smil-timing-Timing-PausedElementsAndActiveDur">pausing * elements</a>. */ public boolean getElementPaused() { throw new Error("NOT IMPLEMENTED"); } /** * Parses the input value and creates TimeCondition instances for the * current instance. * * @param traitName the name of the time condition trait. * @param value the trait value. * @param isBegin true if this should be parsed as a begin value, i.e., * with a 0s default. * @throws DOMException if the input value is invalid. */ protected void parseTimeConditionsTrait(final String traitName, final String value, final boolean isBegin) throws DOMException { try { ownerDocument.timeConditionParser.parseBeginEndAttribute(value, this, isBegin); } catch (IllegalArgumentException iae) { iae.printStackTrace(); throw illegalTraitValue(traitName, value); } } /** * This method can be overridden by specific implementations to validate * that the TimedElementNode is valid, i.e. not in error. * * There are two situations when this method is called: * - parse time. When the document has been fully loaded, it validates all * TimedElementNodes. * - run time. When a new TraitAnimationNode is created, it validates itself * when it is hooked into the tree (i.e., when its parent node is set). */ void validate() {} }