1/* 2 * Copyright (C) 2007 Esmertec AG. 3 * Copyright (C) 2007 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mms.dom.smil; 19 20import org.w3c.dom.DOMException; 21import org.w3c.dom.Element; 22import org.w3c.dom.Node; 23import org.w3c.dom.NodeList; 24import org.w3c.dom.events.DocumentEvent; 25import org.w3c.dom.events.Event; 26import org.w3c.dom.smil.ElementSequentialTimeContainer; 27import org.w3c.dom.smil.ElementTime; 28import org.w3c.dom.smil.SMILDocument; 29import org.w3c.dom.smil.SMILElement; 30import org.w3c.dom.smil.SMILLayoutElement; 31import org.w3c.dom.smil.TimeList; 32 33import com.android.mms.dom.DocumentImpl; 34import com.android.mms.dom.events.EventImpl; 35 36public class SmilDocumentImpl extends DocumentImpl implements SMILDocument, DocumentEvent { 37 /* 38 * The sequential time container cannot be initialized here because the real container 39 * is body, which hasn't been created yet. It will be initialized when the body has 40 * already been created. Please see getBody(). 41 */ 42 ElementSequentialTimeContainer mSeqTimeContainer; 43 44 public final static String SMIL_DOCUMENT_START_EVENT = "SmilDocumentStart"; 45 public final static String SMIL_DOCUMENT_END_EVENT = "SimlDocumentEnd"; 46 47 /* 48 * Internal methods 49 */ 50 public SmilDocumentImpl() { 51 super(); 52 } 53 54 /* 55 * ElementSequentialTimeContainer stuff 56 */ 57 58 public NodeList getActiveChildrenAt(float instant) { 59 return mSeqTimeContainer.getActiveChildrenAt(instant); 60 } 61 62 public NodeList getTimeChildren() { 63 return mSeqTimeContainer.getTimeChildren(); 64 } 65 66 public boolean beginElement() { 67 return mSeqTimeContainer.beginElement(); 68 } 69 70 public boolean endElement() { 71 return mSeqTimeContainer.endElement(); 72 } 73 74 public TimeList getBegin() { 75 return mSeqTimeContainer.getBegin(); 76 } 77 78 public float getDur() { 79 return mSeqTimeContainer.getDur(); 80 } 81 82 public TimeList getEnd() { 83 return mSeqTimeContainer.getEnd(); 84 } 85 86 public short getFill() { 87 return mSeqTimeContainer.getFill(); 88 } 89 90 public short getFillDefault() { 91 return mSeqTimeContainer.getFillDefault(); 92 } 93 94 public float getRepeatCount() { 95 return mSeqTimeContainer.getRepeatCount(); 96 } 97 98 public float getRepeatDur() { 99 return mSeqTimeContainer.getRepeatDur(); 100 } 101 102 public short getRestart() { 103 return mSeqTimeContainer.getRestart(); 104 } 105 106 public void pauseElement() { 107 mSeqTimeContainer.pauseElement(); 108 } 109 110 public void resumeElement() { 111 mSeqTimeContainer.resumeElement(); 112 } 113 114 public void seekElement(float seekTo) { 115 mSeqTimeContainer.seekElement(seekTo); 116 } 117 118 public void setBegin(TimeList begin) throws DOMException { 119 mSeqTimeContainer.setBegin(begin); 120 } 121 122 public void setDur(float dur) throws DOMException { 123 mSeqTimeContainer.setDur(dur); 124 } 125 126 public void setEnd(TimeList end) throws DOMException { 127 mSeqTimeContainer.setEnd(end); 128 } 129 130 public void setFill(short fill) throws DOMException { 131 mSeqTimeContainer.setFill(fill); 132 } 133 134 public void setFillDefault(short fillDefault) throws DOMException { 135 mSeqTimeContainer.setFillDefault(fillDefault); 136 } 137 138 public void setRepeatCount(float repeatCount) throws DOMException { 139 mSeqTimeContainer.setRepeatCount(repeatCount); 140 } 141 142 public void setRepeatDur(float repeatDur) throws DOMException { 143 mSeqTimeContainer.setRepeatDur(repeatDur); 144 } 145 146 public void setRestart(short restart) throws DOMException { 147 mSeqTimeContainer.setRestart(restart); 148 } 149 150 /* 151 * Document Interface 152 */ 153 154 @Override 155 public Element createElement(String tagName) throws DOMException { 156 // Find the appropriate class for this element 157 tagName = tagName.toLowerCase(); 158 if (tagName.equals("text") || 159 tagName.equals("img") || 160 tagName.equals("video")) { 161 return new SmilRegionMediaElementImpl(this, tagName); 162 } else if (tagName.equals("audio")) { 163 return new SmilMediaElementImpl(this, tagName); 164 } else if (tagName.equals("layout")) { 165 return new SmilLayoutElementImpl(this, tagName); 166 } else if (tagName.equals("root-layout")) { 167 return new SmilRootLayoutElementImpl(this, tagName); 168 } else if (tagName.equals("region")) { 169 return new SmilRegionElementImpl(this, tagName); 170 } else if (tagName.equals("ref")) { 171 return new SmilRefElementImpl(this, tagName); 172 } else if (tagName.equals("par")) { 173 return new SmilParElementImpl(this, tagName); 174 } else { 175 // This includes also the structural nodes SMIL, 176 // HEAD, BODY, for which no specific types are defined. 177 return new SmilElementImpl(this, tagName); 178 } 179 } 180 181 @Override 182 public SMILElement getDocumentElement() { 183 Node rootElement = getFirstChild(); 184 if (rootElement == null || !(rootElement instanceof SMILElement)) { 185 // The root doesn't exist. Create a new one. 186 rootElement = createElement("smil"); 187 appendChild(rootElement); 188 } 189 190 return (SMILElement) rootElement; 191 } 192 193 /* 194 * SMILElement Interface 195 */ 196 197 public SMILElement getHead() { 198 Node rootElement = getDocumentElement(); 199 Node headElement = rootElement.getFirstChild(); 200 if (headElement == null || !(headElement instanceof SMILElement)) { 201 // The head doesn't exist. Create a new one. 202 headElement = createElement("head"); 203 rootElement.appendChild(headElement); 204 } 205 206 return (SMILElement) headElement; 207 } 208 209 public SMILElement getBody() { 210 Node rootElement = getDocumentElement(); 211 Node headElement = getHead(); 212 Node bodyElement = headElement.getNextSibling(); 213 if (bodyElement == null || !(bodyElement instanceof SMILElement)) { 214 // The body doesn't exist. Create a new one. 215 bodyElement = createElement("body"); 216 rootElement.appendChild(bodyElement); 217 } 218 219 // Initialize the real sequential time container, which is body. 220 mSeqTimeContainer = new ElementSequentialTimeContainerImpl((SMILElement) bodyElement) { 221 public NodeList getTimeChildren() { 222 return getBody().getElementsByTagName("par"); 223 } 224 225 public boolean beginElement() { 226 Event startEvent = createEvent("Event"); 227 startEvent.initEvent(SMIL_DOCUMENT_START_EVENT, false, false); 228 dispatchEvent(startEvent); 229 return true; 230 } 231 232 public boolean endElement() { 233 Event endEvent = createEvent("Event"); 234 endEvent.initEvent(SMIL_DOCUMENT_END_EVENT, false, false); 235 dispatchEvent(endEvent); 236 return true; 237 } 238 239 public void pauseElement() { 240 // TODO Auto-generated method stub 241 242 } 243 244 public void resumeElement() { 245 // TODO Auto-generated method stub 246 247 } 248 249 public void seekElement(float seekTo) { 250 // TODO Auto-generated method stub 251 252 } 253 254 ElementTime getParentElementTime() { 255 return null; 256 } 257 }; 258 259 return (SMILElement) bodyElement; 260 } 261 262 public SMILLayoutElement getLayout() { 263 Node headElement = getHead(); 264 Node layoutElement = null; 265 266 // Find the layout element under <code>HEAD</code> 267 layoutElement = headElement.getFirstChild(); 268 while ((layoutElement != null) && !(layoutElement instanceof SMILLayoutElement)) { 269 layoutElement = layoutElement.getNextSibling(); 270 } 271 272 if (layoutElement == null) { 273 // The layout doesn't exist. Create a default one. 274 layoutElement = new SmilLayoutElementImpl(this, "layout"); 275 headElement.appendChild(layoutElement); 276 } 277 return (SMILLayoutElement) layoutElement; 278 } 279 280 /* 281 * DocumentEvent Interface 282 */ 283 public Event createEvent(String eventType) throws DOMException { 284 if ("Event".equals(eventType)) { 285 return new EventImpl(); 286 } else { 287 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 288 "Not supported interface"); 289 } 290 } 291} 292