Source Code Cross Referenced for BridgeContext.java in  » Graphic-Library » batik » org » apache » batik » bridge » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Graphic Library » batik » org.apache.batik.bridge 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Licensed to the Apache Software Foundation (ASF) under one or more
0004:           contributor license agreements.  See the NOTICE file distributed with
0005:           this work for additional information regarding copyright ownership.
0006:           The ASF licenses this file to You under the Apache License, Version 2.0
0007:           (the "License"); you may not use this file except in compliance with
0008:           the License.  You may obtain a copy of the License at
0009:
0010:               http://www.apache.org/licenses/LICENSE-2.0
0011:
0012:           Unless required by applicable law or agreed to in writing, software
0013:           distributed under the License is distributed on an "AS IS" BASIS,
0014:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015:           See the License for the specific language governing permissions and
0016:           limitations under the License.
0017:
0018:         */
0019:        package org.apache.batik.bridge;
0020:
0021:        import java.awt.Cursor;
0022:        import java.awt.geom.Dimension2D;
0023:        import java.io.IOException;
0024:        import java.io.InterruptedIOException;
0025:        import java.lang.ref.SoftReference;
0026:        import java.lang.ref.WeakReference;
0027:        import java.net.MalformedURLException;
0028:        import java.net.URL;
0029:        import java.util.HashMap;
0030:        import java.util.HashSet;
0031:        import java.util.Iterator;
0032:        import java.util.LinkedList;
0033:        import java.util.List;
0034:        import java.util.ListIterator;
0035:        import java.util.Map;
0036:        import java.util.Set;
0037:        import java.util.WeakHashMap;
0038:
0039:        import org.apache.batik.bridge.svg12.SVG12BridgeContext;
0040:        import org.apache.batik.bridge.svg12.SVG12BridgeExtension;
0041:        import org.apache.batik.css.engine.CSSContext;
0042:        import org.apache.batik.css.engine.CSSEngine;
0043:        import org.apache.batik.css.engine.CSSEngineEvent;
0044:        import org.apache.batik.css.engine.CSSEngineListener;
0045:        import org.apache.batik.css.engine.CSSEngineUserAgent;
0046:        import org.apache.batik.css.engine.SVGCSSEngine;
0047:        import org.apache.batik.css.engine.SystemColorSupport;
0048:        import org.apache.batik.css.engine.value.Value;
0049:        import org.apache.batik.dom.AbstractNode;
0050:        import org.apache.batik.dom.events.NodeEventTarget;
0051:        import org.apache.batik.dom.svg.AnimatedAttributeListener;
0052:        import org.apache.batik.dom.svg.AnimatedLiveAttributeValue;
0053:        import org.apache.batik.dom.svg.SVGContext;
0054:        import org.apache.batik.dom.svg.SVGDOMImplementation;
0055:        import org.apache.batik.dom.svg.SVGOMDocument;
0056:        import org.apache.batik.dom.svg.SVGOMElement;
0057:        import org.apache.batik.dom.svg.SVGStylableElement;
0058:        import org.apache.batik.dom.xbl.XBLManager;
0059:        import org.apache.batik.gvt.CompositeGraphicsNode;
0060:        import org.apache.batik.gvt.GraphicsNode;
0061:        import org.apache.batik.gvt.TextPainter;
0062:        import org.apache.batik.script.Interpreter;
0063:        import org.apache.batik.script.InterpreterPool;
0064:        import org.apache.batik.util.CSSConstants;
0065:        import org.apache.batik.util.CleanerThread;
0066:        import org.apache.batik.util.ParsedURL;
0067:        import org.apache.batik.util.SVGConstants;
0068:        import org.apache.batik.util.Service;
0069:        import org.apache.batik.util.XMLConstants;
0070:
0071:        import org.w3c.dom.Document;
0072:        import org.w3c.dom.Element;
0073:        import org.w3c.dom.Node;
0074:        import org.w3c.dom.events.Event;
0075:        import org.w3c.dom.events.EventListener;
0076:        import org.w3c.dom.events.EventTarget;
0077:        import org.w3c.dom.events.MouseEvent;
0078:        import org.w3c.dom.events.MutationEvent;
0079:        import org.w3c.dom.svg.SVGDocument;
0080:
0081:        /**
0082:         * This class represents a context used by the various bridges and the
0083:         * builder. A bridge context is associated to a particular document
0084:         * and cannot be reused.
0085:         *
0086:         * The context encapsulates the dynamic bindings between DOM elements
0087:         * and GVT nodes, graphic contexts such as a <tt>GraphicsNodeRenderContext</tt>,
0088:         * and the different objects required by the GVT builder to interpret
0089:         * a SVG DOM tree such as the current viewport or the user agent.
0090:         *
0091:         * @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
0092:         * @version $Id: BridgeContext.java 504819 2007-02-08 08:23:19Z dvholten $
0093:         */
0094:        public class BridgeContext implements  ErrorConstants, CSSContext {
0095:
0096:            /**
0097:             * The document is bridge context is dedicated to.
0098:             */
0099:            protected Document document;
0100:
0101:            /**
0102:             * Whether the document is an SVG 1.2 document.
0103:             */
0104:            protected boolean isSVG12;
0105:
0106:            /**
0107:             * The GVT builder that might be used to create a GVT subtree.
0108:             */
0109:            protected GVTBuilder gvtBuilder;
0110:
0111:            /**
0112:             * The interpreter cache per document.
0113:             * key is the language -
0114:             * value is a Interpreter
0115:             */
0116:            protected Map interpreterMap = new HashMap(7);
0117:
0118:            /**
0119:             * A Map of all the font families already matched. This is
0120:             * to reduce the number of instances of GVTFontFamilies and to
0121:             * hopefully reduce the time taken to search for a matching SVG font.
0122:             */
0123:            private Map fontFamilyMap;
0124:
0125:            /**
0126:             * The viewports.
0127:             * key is an Element -
0128:             * value is a Viewport
0129:             */
0130:            protected Map viewportMap = new WeakHashMap();
0131:
0132:            /**
0133:             * The viewport stack. Used in building time.
0134:             */
0135:            protected List viewportStack = new LinkedList();
0136:
0137:            /**
0138:             * The user agent.
0139:             */
0140:            protected UserAgent userAgent;
0141:
0142:            /**
0143:             * Binding Map:
0144:             * key is an SVG Element -
0145:             * value is a GraphicsNode
0146:             */
0147:            protected Map elementNodeMap;
0148:
0149:            /**
0150:             * Binding Map:
0151:             * key is GraphicsNode -
0152:             * value is a SVG Element.
0153:             */
0154:            protected Map nodeElementMap;
0155:
0156:            /**
0157:             * Bridge Map:
0158:             * Keys are namespace URI - values are HashMap (with keys are local
0159:             * name and values are a Bridge instance).
0160:             */
0161:            protected Map namespaceURIMap;
0162:
0163:            /**
0164:             * Default bridge.
0165:             * When a bridge is requested for an element type that does not have a
0166:             * bridge, and there is no other bridge for elements in the same namespace,
0167:             * the default bridge is returned.  This is used for custom elements,
0168:             * which all use the same bridge type.
0169:             */
0170:            protected Bridge defaultBridge;
0171:
0172:            /**
0173:             * Default bridge reserved namespaces set.
0174:             * Default bridges will not be created for elements that have a
0175:             * namespace URI present in this set.
0176:             */
0177:            protected Set reservedNamespaceSet;
0178:
0179:            /**
0180:             * Element Data Map:
0181:             * This is a general location for elements to 'cache'
0182:             * data.  Such as the graphics tree for a pattern or
0183:             * the Gradient arrays.
0184:             *
0185:             * This is a weak hash map and the data is referenced
0186:             * by SoftReference so both must be referenced elsewhere
0187:             * to stay live.
0188:             */
0189:            protected Map elementDataMap;
0190:
0191:            /**
0192:             * The interpreter pool used to handle scripts.
0193:             */
0194:            protected InterpreterPool interpreterPool;
0195:
0196:            /**
0197:             * The document loader used to load/create Document.
0198:             */
0199:            protected DocumentLoader documentLoader;
0200:
0201:            /**
0202:             * The size of the document.
0203:             */
0204:            protected Dimension2D documentSize;
0205:
0206:            /**
0207:             * The text painter to use. Typically, you can specify the text painter that
0208:             * will be used be text nodes.
0209:             */
0210:            protected TextPainter textPainter;
0211:
0212:            /**
0213:             * Indicates that no DOM listeners should be registered.  In this
0214:             * case the generated GVT tree should be totally independent of
0215:             * the DOM tree (in practice text holds references to the source
0216:             * text elements for font resolution).
0217:             */
0218:            public static final int STATIC = 0;
0219:
0220:            /**
0221:             * Indicates that DOM listeners should be registered to support,
0222:             * 'interactivity' this includes anchors and cursors, but does not
0223:             * include support for DOM modifications.
0224:             */
0225:            public static final int INTERACTIVE = 1;
0226:
0227:            /**
0228:             * Indicates that all DOM listeners should be registered. This supports
0229:             * 'interactivity' (anchors and cursors), as well as DOM modifications
0230:             * listeners to update the GVT rendering tree.
0231:             */
0232:            public static final int DYNAMIC = 2;
0233:
0234:            /**
0235:             * Whether the bridge should support dynamic, or interactive features.
0236:             */
0237:            protected int dynamicStatus = STATIC;
0238:
0239:            /**
0240:             * The update manager.
0241:             */
0242:            protected UpdateManager updateManager;
0243:
0244:            /**
0245:             * The XBL manager.
0246:             */
0247:            protected XBLManager xblManager;
0248:
0249:            /**
0250:             * The bridge context for the primary document, if this is a bridge
0251:             * context for a resource document.
0252:             */
0253:            protected BridgeContext primaryContext;
0254:
0255:            /**
0256:             * Set of WeakReferences to child BridgeContexts.
0257:             */
0258:            protected HashSet childContexts = new HashSet();
0259:
0260:            /**
0261:             * The animation engine for the document.
0262:             */
0263:            protected SVGAnimationEngine animationEngine;
0264:
0265:            /**
0266:             * The animation limiting mode.
0267:             */
0268:            protected int animationLimitingMode;
0269:
0270:            /**
0271:             * The amount of animation limiting.
0272:             */
0273:            protected float animationLimitingAmount;
0274:
0275:            /**
0276:             * By default we share a unique instance of InterpreterPool.
0277:             */
0278:            private static InterpreterPool sharedPool = new InterpreterPool();
0279:
0280:            /**
0281:             * Constructs a new empty bridge context.
0282:             */
0283:            protected BridgeContext() {
0284:            }
0285:
0286:            /**
0287:             * Constructs a new bridge context.
0288:             * @param userAgent the user agent
0289:             */
0290:            public BridgeContext(UserAgent userAgent) {
0291:                this (userAgent, sharedPool, new DocumentLoader(userAgent));
0292:            }
0293:
0294:            /**
0295:             * Constructs a new bridge context.
0296:             * @param userAgent the user agent
0297:             * @param loader document loader
0298:             */
0299:            public BridgeContext(UserAgent userAgent, DocumentLoader loader) {
0300:                this (userAgent, sharedPool, loader);
0301:            }
0302:
0303:            /**
0304:             * Constructs a new bridge context.
0305:             * @param userAgent the user agent
0306:             * @param interpreterPool the interpreter pool
0307:             * @param documentLoader document loader
0308:             */
0309:            public BridgeContext(UserAgent userAgent,
0310:                    InterpreterPool interpreterPool,
0311:                    DocumentLoader documentLoader) {
0312:                this .userAgent = userAgent;
0313:                this .viewportMap.put(userAgent,
0314:                        new UserAgentViewport(userAgent));
0315:                this .interpreterPool = interpreterPool;
0316:                this .documentLoader = documentLoader;
0317:            }
0318:
0319:            /**
0320:             * Calls dispose on this BridgeContext, if it is a child context.
0321:             */
0322:            protected void finalize() {
0323:                if (primaryContext != null) {
0324:                    dispose();
0325:                }
0326:            }
0327:
0328:            /**
0329:             * This function creates a new 'sub' BridgeContext to associated
0330:             * with 'newDoc' if one currently doesn't exist, otherwise it
0331:             * returns the BridgeContext currently associated with the
0332:             * document.
0333:             * @param newDoc The document to get/create a BridgeContext for.
0334:             */
0335:            public BridgeContext createSubBridgeContext(SVGOMDocument newDoc) {
0336:                BridgeContext subCtx;
0337:
0338:                CSSEngine eng = newDoc.getCSSEngine();
0339:                if (eng != null) {
0340:                    subCtx = (BridgeContext) newDoc.getCSSEngine()
0341:                            .getCSSContext();
0342:                    return subCtx;
0343:                }
0344:
0345:                subCtx = createBridgeContext(newDoc);
0346:                subCtx.primaryContext = primaryContext != null ? primaryContext
0347:                        : this ;
0348:                subCtx.primaryContext.childContexts.add(new WeakReference(
0349:                        subCtx));
0350:                subCtx.dynamicStatus = dynamicStatus;
0351:                subCtx.setGVTBuilder(getGVTBuilder());
0352:                subCtx.setTextPainter(getTextPainter());
0353:                subCtx.setDocument(newDoc);
0354:                subCtx.initializeDocument(newDoc);
0355:                if (isInteractive())
0356:                    subCtx.addUIEventListeners(newDoc);
0357:                return subCtx;
0358:            }
0359:
0360:            /**
0361:             * This function creates a new BridgeContext, it mostly
0362:             * exists so subclasses can provide an instance of
0363:             * themselves when a sub BridgeContext is needed.
0364:             */
0365:            public BridgeContext createBridgeContext(SVGOMDocument doc) {
0366:                if (doc.isSVG12()) {
0367:                    return new SVG12BridgeContext(getUserAgent(),
0368:                            getDocumentLoader());
0369:                }
0370:                return new BridgeContext(getUserAgent(), getDocumentLoader());
0371:            }
0372:
0373:            /**
0374:             * Initializes the given document.
0375:             */
0376:            protected void initializeDocument(Document document) {
0377:                SVGOMDocument doc = (SVGOMDocument) document;
0378:                CSSEngine eng = doc.getCSSEngine();
0379:                if (eng == null) {
0380:                    SVGDOMImplementation impl;
0381:                    impl = (SVGDOMImplementation) doc.getImplementation();
0382:                    eng = impl.createCSSEngine(doc, this );
0383:                    eng.setCSSEngineUserAgent(new CSSEngineUserAgentWrapper(
0384:                            userAgent));
0385:                    doc.setCSSEngine(eng);
0386:                    eng.setMedia(userAgent.getMedia());
0387:                    String uri = userAgent.getUserStyleSheetURI();
0388:                    if (uri != null) {
0389:                        try {
0390:                            URL url = new URL(uri);
0391:                            eng.setUserAgentStyleSheet(eng.parseStyleSheet(url,
0392:                                    "all"));
0393:                        } catch (MalformedURLException e) {
0394:                            userAgent.displayError(e);
0395:                        }
0396:                    }
0397:                    eng.setAlternateStyleSheet(userAgent
0398:                            .getAlternateStyleSheet());
0399:                }
0400:            }
0401:
0402:            /**
0403:             * Returns the CSS engine associated with given element.
0404:             */
0405:            public CSSEngine getCSSEngineForElement(Element e) {
0406:                SVGOMDocument doc = (SVGOMDocument) e.getOwnerDocument();
0407:                return doc.getCSSEngine();
0408:            }
0409:
0410:            // properties ////////////////////////////////////////////////////////////
0411:
0412:            /**
0413:             * Sets the text painter that will be used by text nodes. This attributes
0414:             * might be used by bridges (especially SVGTextElementBridge) to set the
0415:             * text painter of each TextNode.
0416:             *
0417:             * @param textPainter the text painter for text nodes
0418:             */
0419:            public void setTextPainter(TextPainter textPainter) {
0420:                this .textPainter = textPainter;
0421:            }
0422:
0423:            /**
0424:             * Returns the text painter that will be used be text nodes.
0425:             */
0426:            public TextPainter getTextPainter() {
0427:                return textPainter;
0428:            }
0429:
0430:            /**
0431:             * Returns the document this bridge context is dedicated to.
0432:             */
0433:            public Document getDocument() {
0434:                return document;
0435:            }
0436:
0437:            /**
0438:             * Sets the document this bridge context is dedicated to, to the
0439:             * specified document.
0440:             * @param document the document
0441:             */
0442:            protected void setDocument(Document document) {
0443:                if (this .document != document) {
0444:                    fontFamilyMap = null;
0445:                }
0446:                this .document = document;
0447:                this .isSVG12 = ((SVGOMDocument) document).isSVG12();
0448:                registerSVGBridges();
0449:            }
0450:
0451:            /**
0452:             * Returns the map of font families
0453:             */
0454:            public Map getFontFamilyMap() {
0455:                if (fontFamilyMap == null) {
0456:                    fontFamilyMap = new HashMap();
0457:                }
0458:                return fontFamilyMap;
0459:            }
0460:
0461:            /**
0462:             * Sets the map of font families to the specified value.
0463:             *
0464:             *@param fontFamilyMap the map of font families
0465:             */
0466:            protected void setFontFamilyMap(Map fontFamilyMap) {
0467:                this .fontFamilyMap = fontFamilyMap;
0468:            }
0469:
0470:            /**
0471:             * Associates a data object with a node so it can be retrieved later.
0472:             * This is primarily used for caching the graphics node generated from
0473:             * a 'pattern' element.  A soft reference to the data object is used.
0474:             */
0475:            public void setElementData(Node n, Object data) {
0476:                if (elementDataMap == null) {
0477:                    elementDataMap = new WeakHashMap();
0478:                }
0479:                elementDataMap.put(n, new SoftReference(data));
0480:            }
0481:
0482:            /**
0483:             * Retrieves a data object associated with the given node.
0484:             */
0485:            public Object getElementData(Node n) {
0486:                if (elementDataMap == null)
0487:                    return null;
0488:                Object o = elementDataMap.get(n);
0489:                if (o == null)
0490:                    return null;
0491:                SoftReference sr = (SoftReference) o;
0492:                o = sr.get();
0493:                if (o == null) {
0494:                    elementDataMap.remove(n);
0495:                }
0496:                return o;
0497:            }
0498:
0499:            /**
0500:             * Returns the user agent of this bridge context.
0501:             */
0502:            public UserAgent getUserAgent() {
0503:                return userAgent;
0504:            }
0505:
0506:            /**
0507:             * Sets the user agent to the specified user agent.
0508:             * @param userAgent the user agent
0509:             */
0510:            protected void setUserAgent(UserAgent userAgent) {
0511:                this .userAgent = userAgent;
0512:            }
0513:
0514:            /**
0515:             * Returns the GVT builder that is currently used to build the GVT tree.
0516:             */
0517:            public GVTBuilder getGVTBuilder() {
0518:                return gvtBuilder;
0519:            }
0520:
0521:            /**
0522:             * Sets the GVT builder that uses this context.
0523:             */
0524:            protected void setGVTBuilder(GVTBuilder gvtBuilder) {
0525:                this .gvtBuilder = gvtBuilder;
0526:            }
0527:
0528:            /**
0529:             * Returns the interpreter pool used to handle scripts.
0530:             */
0531:            public InterpreterPool getInterpreterPool() {
0532:                return interpreterPool;
0533:            }
0534:
0535:            /**
0536:             * Returns the focus manager.
0537:             */
0538:            public FocusManager getFocusManager() {
0539:                return focusManager;
0540:            }
0541:
0542:            /**
0543:             * Returns the cursor manager
0544:             */
0545:            public CursorManager getCursorManager() {
0546:                return cursorManager;
0547:            }
0548:
0549:            /**
0550:             * Sets the interpreter pool used to handle scripts to the
0551:             * specified interpreter pool.
0552:             * @param interpreterPool the interpreter pool
0553:             */
0554:            protected void setInterpreterPool(InterpreterPool interpreterPool) {
0555:                this .interpreterPool = interpreterPool;
0556:            }
0557:
0558:            /**
0559:             * Returns a Interpreter for the specified language.
0560:             *
0561:             * @param language the scripting language
0562:             */
0563:            public Interpreter getInterpreter(String language) {
0564:                if (document == null) {
0565:                    throw new RuntimeException("Unknown document");
0566:                }
0567:                Interpreter interpreter = (Interpreter) interpreterMap
0568:                        .get(language);
0569:                if (interpreter == null) {
0570:                    try {
0571:                        interpreter = interpreterPool.createInterpreter(
0572:                                document, language);
0573:                        interpreterMap.put(language, interpreter);
0574:                    } catch (Exception e) {
0575:                        if (userAgent != null) {
0576:                            userAgent.displayError(e);
0577:                            return null;
0578:                        }
0579:                    }
0580:                }
0581:
0582:                if (interpreter == null) {
0583:                    if (userAgent != null) {
0584:                        userAgent.displayError(new Exception(
0585:                                "Unknown language: " + language));
0586:                    }
0587:                }
0588:
0589:                return interpreter;
0590:            }
0591:
0592:            /**
0593:             * Returns the document loader used to load external documents.
0594:             */
0595:            public DocumentLoader getDocumentLoader() {
0596:                return documentLoader;
0597:            }
0598:
0599:            /**
0600:             * Sets the document loader used to load external documents.
0601:             * @param newDocumentLoader the new document loader
0602:             */
0603:            protected void setDocumentLoader(DocumentLoader newDocumentLoader) {
0604:                this .documentLoader = newDocumentLoader;
0605:            }
0606:
0607:            /**
0608:             * Returns the actual size of the document or null if the document
0609:             * has not been built yet.
0610:             */
0611:            public Dimension2D getDocumentSize() {
0612:                return documentSize;
0613:            }
0614:
0615:            /**
0616:             * Sets the size of the document to the specified dimension.
0617:             *
0618:             * @param d the actual size of the SVG document
0619:             */
0620:            protected void setDocumentSize(Dimension2D d) {
0621:                this .documentSize = d;
0622:            }
0623:
0624:            /**
0625:             * Returns true if the document is dynamic, false otherwise.
0626:             */
0627:            public boolean isDynamic() {
0628:                return (dynamicStatus == DYNAMIC);
0629:            }
0630:
0631:            /**
0632:             * Returns true if the document is interactive, false otherwise.
0633:             */
0634:            public boolean isInteractive() {
0635:                return (dynamicStatus != STATIC);
0636:            }
0637:
0638:            /**
0639:             * Sets the document as a STATIC, INTERACTIVE or DYNAMIC document.
0640:             * Call this method before the build phase
0641:             * (ie. before <tt>gvtBuilder.build(...)</tt>)
0642:             * otherwise, that will have no effect.
0643:             *
0644:             *@param status the document dynamicStatus
0645:             */
0646:            public void setDynamicState(int status) {
0647:                dynamicStatus = status;
0648:            }
0649:
0650:            /**
0651:             * Sets the document as DYNAMIC if <tt>dynamic</tt> is true
0652:             * STATIC otherwise.
0653:             */
0654:            public void setDynamic(boolean dynamic) {
0655:                if (dynamic)
0656:                    setDynamicState(DYNAMIC);
0657:                else
0658:                    setDynamicState(STATIC);
0659:            }
0660:
0661:            /**
0662:             * Sets the document as INTERACTIVE if <tt>interactive</tt> is
0663:             * true STATIC otherwise.
0664:             */
0665:            public void setInteractive(boolean interactive) {
0666:                if (interactive)
0667:                    setDynamicState(INTERACTIVE);
0668:                else
0669:                    setDynamicState(STATIC);
0670:            }
0671:
0672:            /**
0673:             * Returns the update manager, if the bridge supports dynamic features.
0674:             */
0675:            public UpdateManager getUpdateManager() {
0676:                return updateManager;
0677:            }
0678:
0679:            /**
0680:             * Sets the update manager.
0681:             */
0682:            protected void setUpdateManager(UpdateManager um) {
0683:                updateManager = um;
0684:            }
0685:
0686:            /**
0687:             * Sets the update manager on the given BridgeContext.
0688:             */
0689:            protected void setUpdateManager(BridgeContext ctx, UpdateManager um) {
0690:                ctx.setUpdateManager(um);
0691:            }
0692:
0693:            /**
0694:             * Sets the xblManager variable of the given BridgeContext.
0695:             */
0696:            protected void setXBLManager(BridgeContext ctx, XBLManager xm) {
0697:                ctx.xblManager = xm;
0698:            }
0699:
0700:            /**
0701:             * Returns whether the managed document is an SVG 1.2 document.
0702:             */
0703:            public boolean isSVG12() {
0704:                return isSVG12;
0705:            }
0706:
0707:            /**
0708:             * Returns the primary bridge context.
0709:             */
0710:            public BridgeContext getPrimaryBridgeContext() {
0711:                if (primaryContext != null) {
0712:                    return primaryContext;
0713:                }
0714:                return this ;
0715:            }
0716:
0717:            /**
0718:             * Returns an array of the child contexts.
0719:             */
0720:            public BridgeContext[] getChildContexts() {
0721:                BridgeContext[] res = new BridgeContext[childContexts.size()];
0722:                Iterator it = childContexts.iterator();
0723:                for (int i = 0; i < res.length; i++) {
0724:                    WeakReference wr = (WeakReference) it.next();
0725:                    res[i] = (BridgeContext) wr.get();
0726:                }
0727:                return res;
0728:            }
0729:
0730:            /**
0731:             * Returns the AnimationEngine for the document.  Creates one if
0732:             * it doesn't exist.
0733:             */
0734:            public SVGAnimationEngine getAnimationEngine() {
0735:                if (animationEngine == null) {
0736:                    animationEngine = new SVGAnimationEngine(document, this );
0737:                    setAnimationLimitingMode();
0738:                }
0739:                return animationEngine;
0740:            }
0741:
0742:            // reference management //////////////////////////////////////////////////
0743:
0744:            /**
0745:             * Returns a new URIResolver object.
0746:             */
0747:            public URIResolver createURIResolver(SVGDocument doc,
0748:                    DocumentLoader dl) {
0749:                return new URIResolver(doc, dl);
0750:            }
0751:
0752:            /**
0753:             * Returns the node referenced by the specified element by the specified
0754:             * uri. The referenced node can be either an element given by a fragment
0755:             * ID, or the document node.
0756:             * @param e the element referencing
0757:             * @param uri the uri of the referenced node
0758:             */
0759:            public Node getReferencedNode(Element e, String uri) {
0760:                try {
0761:                    SVGDocument document = (SVGDocument) e.getOwnerDocument();
0762:                    URIResolver ur = createURIResolver(document, documentLoader);
0763:                    Node ref = ur.getNode(uri, e);
0764:                    if (ref == null) {
0765:                        throw new BridgeException(this , e, ERR_URI_BAD_TARGET,
0766:                                new Object[] { uri });
0767:                    } else {
0768:                        SVGOMDocument refDoc = (SVGOMDocument) (ref
0769:                                .getNodeType() == Node.DOCUMENT_NODE ? ref
0770:                                : ref.getOwnerDocument());
0771:                        // This is new rather than attaching this BridgeContext
0772:                        // with the new document we now create a whole new
0773:                        // BridgeContext to go with the new document.
0774:                        // This means that the new document has it's own
0775:                        // world of stuff and it should avoid memory leaks
0776:                        // since the new document isn't 'tied into' this
0777:                        // bridge context.
0778:                        if (refDoc != document) {
0779:                            createSubBridgeContext(refDoc);
0780:                        }
0781:                        return ref;
0782:                    }
0783:                } catch (MalformedURLException ex) {
0784:                    throw new BridgeException(this , e, ex, ERR_URI_MALFORMED,
0785:                            new Object[] { uri });
0786:                } catch (InterruptedIOException ex) {
0787:                    throw new InterruptedBridgeException();
0788:                } catch (IOException ex) {
0789:                    ex.printStackTrace();
0790:                    throw new BridgeException(this , e, ex, ERR_URI_IO,
0791:                            new Object[] { uri });
0792:                } catch (SecurityException ex) {
0793:                    throw new BridgeException(this , e, ex, ERR_URI_UNSECURE,
0794:                            new Object[] { uri });
0795:                }
0796:            }
0797:
0798:            /**
0799:             * Returns the element referenced by the specified element by the
0800:             * specified uri. The referenced element can not be a Document.
0801:             *
0802:             * @param e the element referencing
0803:             * @param uri the uri of the referenced element
0804:             */
0805:            public Element getReferencedElement(Element e, String uri) {
0806:                Node ref = getReferencedNode(e, uri);
0807:                if (ref != null && ref.getNodeType() != Node.ELEMENT_NODE) {
0808:                    throw new BridgeException(this , e,
0809:                            ERR_URI_REFERENCE_A_DOCUMENT, new Object[] { uri });
0810:                }
0811:                return (Element) ref;
0812:            }
0813:
0814:            // Viewport //////////////////////////////////////////////////////////////
0815:
0816:            /**
0817:             * Returns the viewport of the specified element.
0818:             *
0819:             * @param e the element interested in its viewport
0820:             */
0821:            public Viewport getViewport(Element e) {
0822:                if (viewportStack != null) {
0823:                    // building time
0824:                    if (viewportStack.size() == 0) {
0825:                        // outermost svg element
0826:                        return (Viewport) viewportMap.get(userAgent);
0827:                    } else {
0828:                        // current viewport
0829:                        return (Viewport) viewportStack.get(0);
0830:                    }
0831:                } else {
0832:                    // search the first parent which has defined a viewport
0833:                    e = SVGUtilities.getParentElement(e);
0834:                    while (e != null) {
0835:                        Viewport viewport = (Viewport) viewportMap.get(e);
0836:                        if (viewport != null) {
0837:                            return viewport;
0838:                        }
0839:                        e = SVGUtilities.getParentElement(e);
0840:                    }
0841:                    return (Viewport) viewportMap.get(userAgent);
0842:                }
0843:            }
0844:
0845:            /**
0846:             * Starts a new viewport from the specified element.
0847:             *
0848:             * @param e the element that defines a new viewport
0849:             * @param viewport the viewport of the element
0850:             */
0851:            public void openViewport(Element e, Viewport viewport) {
0852:                viewportMap.put(e, viewport);
0853:                if (viewportStack == null) {
0854:                    viewportStack = new LinkedList();
0855:                }
0856:                viewportStack.add(0, viewport);
0857:            }
0858:
0859:            public void removeViewport(Element e) {
0860:                viewportMap.remove(e);
0861:            }
0862:
0863:            /**
0864:             * Closes the viewport associated to the specified element.
0865:             * @param e the element that closes its viewport
0866:             */
0867:            public void closeViewport(Element e) {
0868:                //viewportMap.remove(e); FIXME: potential memory leak
0869:                viewportStack.remove(0);
0870:                if (viewportStack.size() == 0) {
0871:                    viewportStack = null;
0872:                }
0873:            }
0874:
0875:            // Bindings //////////////////////////////////////////////////////////////
0876:
0877:            /**
0878:             * Binds the specified GraphicsNode to the specified Element. This method
0879:             * automatically bind the graphics node to the element and the element to
0880:             * the graphics node.
0881:             *
0882:             * @param element the element to bind to the specified graphics node
0883:             * @param node the graphics node to bind to the specified element
0884:             */
0885:            public void bind(Element element, GraphicsNode node) {
0886:                if (elementNodeMap == null) {
0887:                    elementNodeMap = new WeakHashMap();
0888:                    nodeElementMap = new WeakHashMap();
0889:                }
0890:                elementNodeMap.put(element, new SoftReference(node));
0891:                nodeElementMap.put(node, new SoftReference(element));
0892:            }
0893:
0894:            /**
0895:             * Removes the binding of the specified Element.
0896:             *
0897:             * @param element the element to unbind
0898:             */
0899:            public void unbind(Element element) {
0900:                if (elementNodeMap == null) {
0901:                    return;
0902:                }
0903:                GraphicsNode node = null;
0904:                SoftReference sr = (SoftReference) elementNodeMap.get(element);
0905:                if (sr != null)
0906:                    node = (GraphicsNode) sr.get();
0907:                elementNodeMap.remove(element);
0908:                if (node != null)
0909:                    nodeElementMap.remove(node);
0910:            }
0911:
0912:            /**
0913:             * Returns the GraphicsNode associated to the specified Element or
0914:             * null if any.
0915:             *
0916:             * @param element the element associated to the graphics node to return
0917:             */
0918:            public GraphicsNode getGraphicsNode(Element element) {
0919:                if (elementNodeMap != null) {
0920:                    SoftReference sr = (SoftReference) elementNodeMap
0921:                            .get(element);
0922:                    if (sr != null)
0923:                        return (GraphicsNode) sr.get();
0924:                }
0925:                return null;
0926:            }
0927:
0928:            /**
0929:             * Returns the Element associated to the specified GraphicsNode or
0930:             * null if any.
0931:             *
0932:             * @param node the graphics node associated to the element to return
0933:             */
0934:            public Element getElement(GraphicsNode node) {
0935:                if (nodeElementMap != null) {
0936:                    SoftReference sr = (SoftReference) nodeElementMap.get(node);
0937:                    if (sr != null)
0938:                        return (Element) sr.get();
0939:                }
0940:                return null;
0941:            }
0942:
0943:            // Bridge management /////////////////////////////////////////////////////
0944:
0945:            /**
0946:             * Returns true if the specified element has a GraphicsNodeBridge
0947:             * associated to it, false otherwise.
0948:             *
0949:             * @param element the element
0950:             */
0951:            public boolean hasGraphicsNodeBridge(Element element) {
0952:                if (namespaceURIMap == null || element == null) {
0953:                    return false;
0954:                }
0955:                String localName = element.getLocalName();
0956:                String namespaceURI = element.getNamespaceURI();
0957:                namespaceURI = ((namespaceURI == null) ? "" : namespaceURI);
0958:                HashMap localNameMap = (HashMap) namespaceURIMap
0959:                        .get(namespaceURI);
0960:                if (localNameMap == null) {
0961:                    return false;
0962:                }
0963:                return (localNameMap.get(localName) instanceof  GraphicsNodeBridge);
0964:            }
0965:
0966:            /**
0967:             * Returns the bridge associated with the specified element.
0968:             *
0969:             * @param element the element
0970:             */
0971:            public Bridge getBridge(Element element) {
0972:                if (namespaceURIMap == null || element == null) {
0973:                    return null;
0974:                }
0975:                String localName = element.getLocalName();
0976:                String namespaceURI = element.getNamespaceURI();
0977:                namespaceURI = ((namespaceURI == null) ? "" : namespaceURI);
0978:                return getBridge(namespaceURI, localName);
0979:            }
0980:
0981:            /**
0982:             * Returns the bridge associated with the element type
0983:             *
0984:             * @param namespaceURI namespace of the requested element
0985:             * @param localName element's local name
0986:             *
0987:             */
0988:            public Bridge getBridge(String namespaceURI, String localName) {
0989:                Bridge bridge = null;
0990:                if (namespaceURIMap != null) {
0991:                    HashMap localNameMap = (HashMap) namespaceURIMap
0992:                            .get(namespaceURI);
0993:                    if (localNameMap != null) {
0994:                        bridge = (Bridge) localNameMap.get(localName);
0995:                    }
0996:                }
0997:                if (bridge == null
0998:                        && (reservedNamespaceSet == null || !reservedNamespaceSet
0999:                                .contains(namespaceURI))) {
1000:                    bridge = defaultBridge;
1001:                }
1002:                if (isDynamic()) {
1003:                    return bridge == null ? null : bridge.getInstance();
1004:                } else {
1005:                    return bridge;
1006:                }
1007:            }
1008:
1009:            /**
1010:             * Associates the specified <tt>Bridge</tt> object with the specified
1011:             * namespace URI and local name.
1012:             * @param namespaceURI the namespace URI
1013:             * @param localName the local name
1014:             * @param bridge the bridge that manages the element
1015:             */
1016:            public void putBridge(String namespaceURI, String localName,
1017:                    Bridge bridge) {
1018:                // start assert
1019:                if (!(namespaceURI.equals(bridge.getNamespaceURI()) && localName
1020:                        .equals(bridge.getLocalName()))) {
1021:                    throw new Error("Invalid Bridge: " + namespaceURI + "/"
1022:                            + bridge.getNamespaceURI() + " " + localName + "/"
1023:                            + bridge.getLocalName() + " " + bridge.getClass());
1024:                }
1025:                // end assert
1026:                if (namespaceURIMap == null) {
1027:                    namespaceURIMap = new HashMap();
1028:                }
1029:                namespaceURI = ((namespaceURI == null) ? "" : namespaceURI);
1030:                HashMap localNameMap = (HashMap) namespaceURIMap
1031:                        .get(namespaceURI);
1032:                if (localNameMap == null) {
1033:                    localNameMap = new HashMap();
1034:                    namespaceURIMap.put(namespaceURI, localNameMap);
1035:                }
1036:                localNameMap.put(localName, bridge);
1037:            }
1038:
1039:            /**
1040:             * Associates the specified <tt>Bridge</tt> object with it's
1041:             * namespace URI and local name.
1042:             *
1043:             * @param bridge the bridge that manages the element
1044:             */
1045:            public void putBridge(Bridge bridge) {
1046:                putBridge(bridge.getNamespaceURI(), bridge.getLocalName(),
1047:                        bridge);
1048:            }
1049:
1050:            /**
1051:             * Removes the <tt>Bridge</tt> object associated to the specified
1052:             * namespace URI and local name.
1053:             *
1054:             * @param namespaceURI the namespace URI
1055:             * @param localName the local name
1056:             */
1057:            public void removeBridge(String namespaceURI, String localName) {
1058:                if (namespaceURIMap == null) {
1059:                    return;
1060:                }
1061:                namespaceURI = ((namespaceURI == null) ? "" : namespaceURI);
1062:                HashMap localNameMap = (HashMap) namespaceURIMap
1063:                        .get(namespaceURI);
1064:                if (localNameMap != null) {
1065:                    localNameMap.remove(localName);
1066:                    if (localNameMap.isEmpty()) {
1067:                        namespaceURIMap.remove(namespaceURI);
1068:                        if (namespaceURIMap.isEmpty()) {
1069:                            namespaceURIMap = null;
1070:                        }
1071:                    }
1072:                }
1073:            }
1074:
1075:            /**
1076:             * Sets the <tt>Bridge</tt> object to be used for foreign
1077:             * namespace elements.
1078:             *
1079:             * @param bridge the bridge that manages the element
1080:             */
1081:            public void setDefaultBridge(Bridge bridge) {
1082:                defaultBridge = bridge;
1083:            }
1084:
1085:            /**
1086:             * Adds a namespace URI to avoid when creating default bridges.
1087:             */
1088:            public void putReservedNamespaceURI(String namespaceURI) {
1089:                if (namespaceURI == null) {
1090:                    namespaceURI = "";
1091:                }
1092:                if (reservedNamespaceSet == null) {
1093:                    reservedNamespaceSet = new HashSet();
1094:                }
1095:                reservedNamespaceSet.add(namespaceURI);
1096:            }
1097:
1098:            /**
1099:             * Removes a namespace URI to avoid when creating default bridges.
1100:             */
1101:            public void removeReservedNamespaceURI(String namespaceURI) {
1102:                if (namespaceURI == null) {
1103:                    namespaceURI = "";
1104:                }
1105:                if (reservedNamespaceSet != null) {
1106:                    reservedNamespaceSet.remove(namespaceURI);
1107:                    if (reservedNamespaceSet.isEmpty()) {
1108:                        reservedNamespaceSet = null;
1109:                    }
1110:                }
1111:            }
1112:
1113:            // dynamic support ////////////////////////////////////////////////////////
1114:
1115:            /**
1116:             * The list of all EventListener attached by bridges that need to
1117:             * be removed on a dispose() call.
1118:             */
1119:            protected Set eventListenerSet = new HashSet();
1120:
1121:            /**
1122:             * The DOM EventListener to receive 'DOMCharacterDataModified' event.
1123:             */
1124:            protected EventListener domCharacterDataModifiedEventListener;
1125:
1126:            /**
1127:             * The DOM EventListener to receive 'DOMAttrModified' event.
1128:             */
1129:            protected EventListener domAttrModifiedEventListener;
1130:
1131:            /**
1132:             * The DOM EventListener to receive 'DOMNodeInserted' event.
1133:             */
1134:            protected EventListener domNodeInsertedEventListener;
1135:
1136:            /**
1137:             * The DOM EventListener to receive 'DOMNodeRemoved' event.
1138:             */
1139:            protected EventListener domNodeRemovedEventListener;
1140:
1141:            /**
1142:             * The CSSEngine listener to receive CSSEngineEvent.
1143:             */
1144:            protected CSSEngineListener cssPropertiesChangedListener;
1145:
1146:            /**
1147:             * The listener to receive notification of animated attribute changes.
1148:             */
1149:            protected AnimatedAttributeListener animatedAttributeListener;
1150:
1151:            /**
1152:             * The EventListener that is responsible of managing DOM focus event.
1153:             */
1154:            protected FocusManager focusManager;
1155:
1156:            /**
1157:             * Manages cursors and performs caching when appropriate
1158:             */
1159:            protected CursorManager cursorManager = new CursorManager(this );
1160:
1161:            /**
1162:             * Adds EventListeners to the input document to handle the cursor
1163:             * property.
1164:             * This is not done in the addDOMListeners method because
1165:             * addDOMListeners is only used for dynamic content whereas
1166:             * cursor support is provided for all content.
1167:             * Also note that it is very important that the listeners be
1168:             * registered for the capture phase as the 'default' behavior
1169:             * for cursors is handled by the BridgeContext during the
1170:             * capture phase and the 'custom' behavior (handling of 'auto'
1171:             * on anchors, for example), is handled during the bubbling phase.
1172:             */
1173:            public void addUIEventListeners(Document doc) {
1174:                NodeEventTarget evtTarget = (NodeEventTarget) doc
1175:                        .getDocumentElement();
1176:
1177:                DOMMouseOverEventListener domMouseOverListener = new DOMMouseOverEventListener();
1178:                evtTarget.addEventListenerNS(
1179:                        XMLConstants.XML_EVENTS_NAMESPACE_URI,
1180:                        SVGConstants.SVG_EVENT_MOUSEOVER, domMouseOverListener,
1181:                        true, null);
1182:                storeEventListenerNS(evtTarget,
1183:                        XMLConstants.XML_EVENTS_NAMESPACE_URI,
1184:                        SVGConstants.SVG_EVENT_MOUSEOVER, domMouseOverListener,
1185:                        true);
1186:
1187:                DOMMouseOutEventListener domMouseOutListener = new DOMMouseOutEventListener();
1188:                evtTarget.addEventListenerNS(
1189:                        XMLConstants.XML_EVENTS_NAMESPACE_URI,
1190:                        SVGConstants.SVG_EVENT_MOUSEOUT, domMouseOutListener,
1191:                        true, null);
1192:                storeEventListenerNS(evtTarget,
1193:                        XMLConstants.XML_EVENTS_NAMESPACE_URI,
1194:                        SVGConstants.SVG_EVENT_MOUSEOUT, domMouseOutListener,
1195:                        true);
1196:
1197:            }
1198:
1199:            public void removeUIEventListeners(Document doc) {
1200:                EventTarget evtTarget = (EventTarget) doc.getDocumentElement();
1201:                synchronized (eventListenerSet) {
1202:                    Iterator i = eventListenerSet.iterator();
1203:                    while (i.hasNext()) {
1204:                        EventListenerMememto elm = (EventListenerMememto) i
1205:                                .next();
1206:                        NodeEventTarget et = elm.getTarget();
1207:                        if (et == evtTarget) {
1208:                            EventListener el = elm.getListener();
1209:                            boolean uc = elm.getUseCapture();
1210:                            String t = elm.getEventType();
1211:                            boolean n = elm.getNamespaced();
1212:                            if (et == null || el == null || t == null) {
1213:                                continue;
1214:                            }
1215:                            if (n) {
1216:                                String ns = elm.getNamespaceURI();
1217:                                et.removeEventListenerNS(ns, t, el, uc);
1218:                            } else {
1219:                                et.removeEventListener(t, el, uc);
1220:                            }
1221:                        }
1222:                    }
1223:                }
1224:            }
1225:
1226:            /**
1227:             * Adds EventListeners to the DOM and CSSEngineListener to the
1228:             * CSSEngine to handle any modifications on the DOM tree or style
1229:             * properties and update the GVT tree in response.
1230:             */
1231:            public void addDOMListeners() {
1232:                SVGOMDocument doc = (SVGOMDocument) document;
1233:
1234:                domAttrModifiedEventListener = new DOMAttrModifiedEventListener();
1235:                doc.addEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
1236:                        "DOMAttrModified", domAttrModifiedEventListener, true,
1237:                        null);
1238:
1239:                domNodeInsertedEventListener = new DOMNodeInsertedEventListener();
1240:                doc.addEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
1241:                        "DOMNodeInserted", domNodeInsertedEventListener, true,
1242:                        null);
1243:
1244:                domNodeRemovedEventListener = new DOMNodeRemovedEventListener();
1245:                doc.addEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
1246:                        "DOMNodeRemoved", domNodeRemovedEventListener, true,
1247:                        null);
1248:
1249:                domCharacterDataModifiedEventListener = new DOMCharacterDataModifiedEventListener();
1250:                doc.addEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
1251:                        "DOMCharacterDataModified",
1252:                        domCharacterDataModifiedEventListener, true, null);
1253:
1254:                animatedAttributeListener = new AnimatedAttrListener();
1255:                doc.addAnimatedAttributeListener(animatedAttributeListener);
1256:
1257:                focusManager = new FocusManager(document);
1258:
1259:                CSSEngine cssEngine = doc.getCSSEngine();
1260:                cssPropertiesChangedListener = new CSSPropertiesChangedListener();
1261:                cssEngine.addCSSEngineListener(cssPropertiesChangedListener);
1262:            }
1263:
1264:            /**
1265:             * Removes event listeners from the DOM and CSS engine.
1266:             */
1267:            protected void removeDOMListeners() {
1268:                SVGOMDocument doc = (SVGOMDocument) document;
1269:
1270:                doc.removeEventListenerNS(
1271:                        XMLConstants.XML_EVENTS_NAMESPACE_URI,
1272:                        "DOMAttrModified", domAttrModifiedEventListener, true);
1273:                doc.removeEventListenerNS(
1274:                        XMLConstants.XML_EVENTS_NAMESPACE_URI,
1275:                        "DOMNodeInserted", domNodeInsertedEventListener, true);
1276:                doc.removeEventListenerNS(
1277:                        XMLConstants.XML_EVENTS_NAMESPACE_URI,
1278:                        "DOMNodeRemoved", domNodeRemovedEventListener, true);
1279:                doc.removeEventListenerNS(
1280:                        XMLConstants.XML_EVENTS_NAMESPACE_URI,
1281:                        "DOMCharacterDataModified",
1282:                        domCharacterDataModifiedEventListener, true);
1283:
1284:                doc.removeAnimatedAttributeListener(animatedAttributeListener);
1285:
1286:                CSSEngine cssEngine = doc.getCSSEngine();
1287:                if (cssEngine != null) {
1288:                    cssEngine
1289:                            .removeCSSEngineListener(cssPropertiesChangedListener);
1290:                    cssEngine.dispose();
1291:                    doc.setCSSEngine(null);
1292:                }
1293:            }
1294:
1295:            /**
1296:             * Adds to the eventListenerSet the specified event listener
1297:             * registration.
1298:             */
1299:            protected void storeEventListener(EventTarget t, String s,
1300:                    EventListener l, boolean b) {
1301:                synchronized (eventListenerSet) {
1302:                    eventListenerSet.add(new EventListenerMememto(t, s, l, b,
1303:                            this ));
1304:                }
1305:            }
1306:
1307:            /**
1308:             * Adds to the eventListenerSet the specified event listener
1309:             * registration.
1310:             */
1311:            protected void storeEventListenerNS(EventTarget t, String n,
1312:                    String s, EventListener l, boolean b) {
1313:                synchronized (eventListenerSet) {
1314:                    eventListenerSet.add(new EventListenerMememto(t, n, s, l,
1315:                            b, this ));
1316:                }
1317:            }
1318:
1319:            public static class SoftReferenceMememto extends
1320:                    CleanerThread.SoftReferenceCleared {
1321:                Object mememto;
1322:                Set set;
1323:
1324:                // String refStr;
1325:                SoftReferenceMememto(Object ref, Object mememto, Set set) {
1326:                    super (ref);
1327:                    // refStr = ref.toString();
1328:                    this .mememto = mememto;
1329:                    this .set = set;
1330:                }
1331:
1332:                public void cleared() {
1333:                    synchronized (set) {
1334:                        // System.err.println("SRClear: " + refStr);
1335:                        set.remove(mememto);
1336:                        mememto = null;
1337:                        set = null;
1338:                    }
1339:                }
1340:            }
1341:
1342:            /**
1343:             * A class used to store an EventListener added to the DOM.
1344:             */
1345:            protected static class EventListenerMememto {
1346:
1347:                public SoftReference target; // Soft ref to EventTarget
1348:                public SoftReference listener; // Soft ref to EventListener
1349:                public boolean useCapture;
1350:                public String namespaceURI;
1351:                public String eventType;
1352:                public boolean namespaced;
1353:
1354:                public EventListenerMememto(EventTarget t, String s,
1355:                        EventListener l, boolean b, BridgeContext ctx) {
1356:                    Set set = ctx.eventListenerSet;
1357:                    target = new SoftReferenceMememto(t, this , set);
1358:                    listener = new SoftReferenceMememto(l, this , set);
1359:                    eventType = s;
1360:                    useCapture = b;
1361:                }
1362:
1363:                public EventListenerMememto(EventTarget t, String n, String s,
1364:                        EventListener l, boolean b, BridgeContext ctx) {
1365:                    this (t, s, l, b, ctx);
1366:                    namespaceURI = n;
1367:                    namespaced = true;
1368:                }
1369:
1370:                public EventListener getListener() {
1371:                    return (EventListener) listener.get();
1372:                }
1373:
1374:                public NodeEventTarget getTarget() {
1375:                    return (NodeEventTarget) target.get();
1376:                }
1377:
1378:                public boolean getUseCapture() {
1379:                    return useCapture;
1380:                }
1381:
1382:                public String getNamespaceURI() {
1383:                    return namespaceURI;
1384:                }
1385:
1386:                public String getEventType() {
1387:                    return eventType;
1388:                }
1389:
1390:                public boolean getNamespaced() {
1391:                    return namespaced;
1392:                }
1393:            }
1394:
1395:            /**
1396:             * Adds the GVT listener for AWT event support.
1397:             */
1398:            public void addGVTListener(Document doc) {
1399:                BridgeEventSupport.addGVTListener(this , doc);
1400:            }
1401:
1402:            /**
1403:             * Clears the list of child BridgeContexts and disposes them if there are
1404:             * no more references to them.
1405:             */
1406:            protected void clearChildContexts() {
1407:                childContexts.clear();
1408:            }
1409:
1410:            /**
1411:             * Disposes this BridgeContext.
1412:             */
1413:            public void dispose() {
1414:                clearChildContexts();
1415:
1416:                synchronized (eventListenerSet) {
1417:                    // remove all listeners added by Bridges
1418:                    Iterator iter = eventListenerSet.iterator();
1419:                    while (iter.hasNext()) {
1420:                        EventListenerMememto m = (EventListenerMememto) iter
1421:                                .next();
1422:                        NodeEventTarget et = m.getTarget();
1423:                        EventListener el = m.getListener();
1424:                        boolean uc = m.getUseCapture();
1425:                        String t = m.getEventType();
1426:                        boolean n = m.getNamespaced();
1427:                        if (et == null || el == null || t == null) {
1428:                            continue;
1429:                        }
1430:                        if (n) {
1431:                            String ns = m.getNamespaceURI();
1432:                            et.removeEventListenerNS(ns, t, el, uc);
1433:                        } else {
1434:                            et.removeEventListener(t, el, uc);
1435:                        }
1436:                    }
1437:                }
1438:
1439:                if (document != null) {
1440:                    removeDOMListeners();
1441:                }
1442:
1443:                if (animationEngine != null) {
1444:                    animationEngine.dispose();
1445:                    animationEngine = null;
1446:                }
1447:
1448:                Iterator iter = interpreterMap.values().iterator();
1449:                while (iter.hasNext()) {
1450:                    Interpreter interpreter = (Interpreter) iter.next();
1451:                    if (interpreter != null)
1452:                        interpreter.dispose();
1453:                }
1454:                interpreterMap.clear();
1455:
1456:                if (focusManager != null) {
1457:                    focusManager.dispose();
1458:                }
1459:                if (elementDataMap != null) {
1460:                    elementDataMap.clear();
1461:                }
1462:                if (nodeElementMap != null) {
1463:                    nodeElementMap.clear();
1464:                }
1465:                if (elementNodeMap != null) {
1466:                    elementNodeMap.clear();
1467:                }
1468:            }
1469:
1470:            /**
1471:             * Returns the SVGContext associated to the specified Node or null if
1472:             * there is none.
1473:             */
1474:            protected static SVGContext getSVGContext(Node node) {
1475:                if (node instanceof  SVGOMElement) {
1476:                    return ((SVGOMElement) node).getSVGContext();
1477:                } else {
1478:                    return null;
1479:                }
1480:            }
1481:
1482:            /**
1483:             * Returns the BridgeUpdateHandler associated to the specified Node
1484:             * or null if there is none.
1485:             */
1486:            protected static BridgeUpdateHandler getBridgeUpdateHandler(
1487:                    Node node) {
1488:                SVGContext ctx = getSVGContext(node);
1489:                return (ctx == null) ? null : (BridgeUpdateHandler) ctx;
1490:            }
1491:
1492:            /**
1493:             * The DOM EventListener invoked when an attribute is modified.
1494:             */
1495:            protected class DOMAttrModifiedEventListener implements 
1496:                    EventListener {
1497:
1498:                /**
1499:                 * Creates a new DOMAttrModifiedEventListener.
1500:                 */
1501:                public DOMAttrModifiedEventListener() {
1502:                }
1503:
1504:                /**
1505:                 * Handles 'DOMAttrModified' event type.
1506:                 */
1507:                public void handleEvent(Event evt) {
1508:                    Node node = (Node) evt.getTarget();
1509:                    BridgeUpdateHandler h = getBridgeUpdateHandler(node);
1510:                    if (h != null) {
1511:                        try {
1512:                            h.handleDOMAttrModifiedEvent((MutationEvent) evt);
1513:                        } catch (Exception e) {
1514:                            userAgent.displayError(e);
1515:                        }
1516:                    }
1517:                }
1518:            }
1519:
1520:            /**
1521:             * The DOM EventListener invoked when the mouse exits an element
1522:             */
1523:            protected class DOMMouseOutEventListener implements  EventListener {
1524:
1525:                /**
1526:                 * Creates a new DOMMouseOutEventListener.
1527:                 */
1528:                public DOMMouseOutEventListener() {
1529:                }
1530:
1531:                /**
1532:                 * Handles 'mouseout' MouseEvent event type.
1533:                 */
1534:                public void handleEvent(Event evt) {
1535:                    MouseEvent me = (MouseEvent) evt;
1536:                    Element newTarget = (Element) me.getRelatedTarget();
1537:                    Cursor cursor = CursorManager.DEFAULT_CURSOR;
1538:                    if (newTarget != null)
1539:                        cursor = CSSUtilities.convertCursor(newTarget,
1540:                                BridgeContext.this );
1541:                    if (cursor == null)
1542:                        cursor = CursorManager.DEFAULT_CURSOR;
1543:
1544:                    userAgent.setSVGCursor(cursor);
1545:                }
1546:            }
1547:
1548:            /**
1549:             * The DOM EventListener invoked when the mouse mouves over a new
1550:             * element.
1551:             *
1552:             * Here is how cursors are handled:
1553:             *
1554:             */
1555:            protected class DOMMouseOverEventListener implements  EventListener {
1556:
1557:                /**
1558:                 * Creates a new DOMMouseOverEventListener.
1559:                 */
1560:                public DOMMouseOverEventListener() {
1561:                }
1562:
1563:                /**
1564:                 * Handles 'mouseover' MouseEvent event type.
1565:                 */
1566:                public void handleEvent(Event evt) {
1567:                    Element target = (Element) evt.getTarget();
1568:                    Cursor cursor = CSSUtilities.convertCursor(target,
1569:                            BridgeContext.this );
1570:
1571:                    if (cursor != null) {
1572:                        userAgent.setSVGCursor(cursor);
1573:                    }
1574:                }
1575:            }
1576:
1577:            /**
1578:             * The DOM EventListener invoked when a node is added.
1579:             */
1580:            protected class DOMNodeInsertedEventListener implements 
1581:                    EventListener {
1582:
1583:                /**
1584:                 * Creates a new DOMNodeInsertedEventListener.
1585:                 */
1586:                public DOMNodeInsertedEventListener() {
1587:                }
1588:
1589:                /**
1590:                 * Handles 'DOMNodeInserted' event type.
1591:                 */
1592:                public void handleEvent(Event evt) {
1593:                    MutationEvent me = (MutationEvent) evt;
1594:                    BridgeUpdateHandler h = getBridgeUpdateHandler(me
1595:                            .getRelatedNode());
1596:                    if (h != null) {
1597:                        try {
1598:                            h.handleDOMNodeInsertedEvent(me);
1599:                        } catch (InterruptedBridgeException ibe) {
1600:                            /* do nothing */
1601:                        } catch (Exception e) {
1602:                            userAgent.displayError(e);
1603:                        }
1604:                    }
1605:                }
1606:            }
1607:
1608:            /**
1609:             * The DOM EventListener invoked when a node is removed.
1610:             */
1611:            protected class DOMNodeRemovedEventListener implements 
1612:                    EventListener {
1613:
1614:                /**
1615:                 * Creates a new DOMNodeRemovedEventListener.
1616:                 */
1617:                public DOMNodeRemovedEventListener() {
1618:                }
1619:
1620:                /**
1621:                 * Handles 'DOMNodeRemoved' event type.
1622:                 */
1623:                public void handleEvent(Event evt) {
1624:                    Node node = (Node) evt.getTarget();
1625:                    BridgeUpdateHandler h = getBridgeUpdateHandler(node);
1626:                    if (h != null) {
1627:                        try {
1628:                            h.handleDOMNodeRemovedEvent((MutationEvent) evt);
1629:                        } catch (Exception e) {
1630:                            userAgent.displayError(e);
1631:                        }
1632:                    }
1633:                }
1634:            }
1635:
1636:            /**
1637:             * The DOM EventListener invoked when a character data is changed.
1638:             */
1639:            protected class DOMCharacterDataModifiedEventListener implements 
1640:                    EventListener {
1641:
1642:                /**
1643:                 * Creates a new DOMCharacterDataModifiedEventListener.
1644:                 */
1645:                public DOMCharacterDataModifiedEventListener() {
1646:                }
1647:
1648:                /**
1649:                 * Handles 'DOMCharacterDataModified' event type.
1650:                 */
1651:                public void handleEvent(Event evt) {
1652:                    Node node = (Node) evt.getTarget();
1653:                    while (node != null && !(node instanceof  SVGOMElement)) {
1654:                        node = (Node) ((AbstractNode) node)
1655:                                .getParentNodeEventTarget();
1656:                    }
1657:                    BridgeUpdateHandler h = getBridgeUpdateHandler(node);
1658:                    if (h != null) {
1659:                        try {
1660:                            h
1661:                                    .handleDOMCharacterDataModified((MutationEvent) evt);
1662:                        } catch (Exception e) {
1663:                            userAgent.displayError(e);
1664:                        }
1665:                    }
1666:                }
1667:            }
1668:
1669:            /**
1670:             * The CSSEngineListener invoked when CSS properties are modified
1671:             * on a particular element.
1672:             */
1673:            protected class CSSPropertiesChangedListener implements 
1674:                    CSSEngineListener {
1675:
1676:                /**
1677:                 * Creates a new CSSPropertiesChangedListener.
1678:                 */
1679:                public CSSPropertiesChangedListener() {
1680:                }
1681:
1682:                /**
1683:                 * Handles CSSEngineEvent that describes the CSS properties
1684:                 * that have changed on a particular element.
1685:                 */
1686:                public void propertiesChanged(CSSEngineEvent evt) {
1687:                    Element elem = evt.getElement();
1688:                    SVGContext ctx = getSVGContext(elem);
1689:                    if (ctx == null) {
1690:                        GraphicsNode pgn = getGraphicsNode((Element) elem
1691:                                .getParentNode());
1692:                        if ((pgn == null)
1693:                                || !(pgn instanceof  CompositeGraphicsNode)) {
1694:                            // Something changed in this element but we really don't
1695:                            // care since its parent isn't displayed either.
1696:                            return;
1697:                        }
1698:                        CompositeGraphicsNode parent = (CompositeGraphicsNode) pgn;
1699:                        // Check if 'display' changed on this element.
1700:
1701:                        int[] properties = evt.getProperties();
1702:                        for (int i = 0; i < properties.length; ++i) {
1703:                            if (properties[i] == SVGCSSEngine.DISPLAY_INDEX) {
1704:                                if (!CSSUtilities.convertDisplay(elem)) {
1705:                                    // (Still) Not displayed
1706:                                    break;
1707:                                }
1708:                                // build the graphics node
1709:                                GVTBuilder builder = getGVTBuilder();
1710:                                GraphicsNode childNode = builder.build(
1711:                                        BridgeContext.this , elem);
1712:                                if (childNode == null) {
1713:                                    // the added element is not a graphic element?
1714:                                    break;
1715:                                }
1716:                                int idx = -1;
1717:                                for (Node ps = elem.getPreviousSibling(); ps != null; ps = ps
1718:                                        .getPreviousSibling()) {
1719:                                    if (ps.getNodeType() != Node.ELEMENT_NODE)
1720:                                        continue;
1721:                                    Element pse = (Element) ps;
1722:                                    GraphicsNode gn = getGraphicsNode(pse);
1723:                                    if (gn == null)
1724:                                        continue;
1725:                                    idx = parent.indexOf(gn);
1726:                                    if (idx == -1)
1727:                                        continue;
1728:                                    break;
1729:                                }
1730:                                // insert after prevSibling, if
1731:                                // it was -1 this becomes 0 (first slot)
1732:                                idx++;
1733:                                parent.add(idx, childNode);
1734:                                break;
1735:                            }
1736:                        }
1737:                    }
1738:                    if (ctx != null && (ctx instanceof  BridgeUpdateHandler)) {
1739:                        ((BridgeUpdateHandler) ctx).handleCSSEngineEvent(evt);
1740:                    }
1741:                }
1742:            }
1743:
1744:            /**
1745:             * A listener class for changes to animated attributes in the document.
1746:             */
1747:            protected class AnimatedAttrListener implements 
1748:                    AnimatedAttributeListener {
1749:
1750:                /**
1751:                 * Creates a new AnimatedAttributeListener.
1752:                 */
1753:                public AnimatedAttrListener() {
1754:                }
1755:
1756:                /**
1757:                 * Called to notify an object of a change to the animated value of
1758:                 * an animated XML attribute.
1759:                 * @param e the owner element of the changed animated attribute
1760:                 * @param alav the AnimatedLiveAttributeValue that changed
1761:                 */
1762:                public void animatedAttributeChanged(Element e,
1763:                        AnimatedLiveAttributeValue alav) {
1764:                    BridgeUpdateHandler h = getBridgeUpdateHandler(e);
1765:                    if (h != null) {
1766:                        try {
1767:                            h.handleAnimatedAttributeChanged(alav);
1768:                        } catch (Exception ex) {
1769:                            userAgent.displayError(ex);
1770:                        }
1771:                    }
1772:                }
1773:
1774:                /**
1775:                 * Called to notify an object of a change to the value of an 'other'
1776:                 * animation.
1777:                 * @param e the element being animated
1778:                 * @param type the type of animation whose value changed
1779:                 */
1780:                public void otherAnimationChanged(Element e, String type) {
1781:                    BridgeUpdateHandler h = getBridgeUpdateHandler(e);
1782:                    if (h != null) {
1783:                        try {
1784:                            h.handleOtherAnimationChanged(type);
1785:                        } catch (Exception ex) {
1786:                            userAgent.displayError(ex);
1787:                        }
1788:                    }
1789:                }
1790:            }
1791:
1792:            // CSS context ////////////////////////////////////////////////////////////
1793:
1794:            /**
1795:             * Returns the Value corresponding to the given system color.
1796:             */
1797:            public Value getSystemColor(String ident) {
1798:                return SystemColorSupport.getSystemColor(ident);
1799:            }
1800:
1801:            /**
1802:             * Returns the value corresponding to the default font.
1803:             */
1804:            public Value getDefaultFontFamily() {
1805:                // No cache needed since the default font family is asked only
1806:                // one time on the root element (only if it does not have its
1807:                // own font-family).
1808:                SVGOMDocument doc = (SVGOMDocument) document;
1809:                SVGStylableElement root = (SVGStylableElement) doc
1810:                        .getRootElement();
1811:                String str = userAgent.getDefaultFontFamily();
1812:                return doc.getCSSEngine().parsePropertyValue(root,
1813:                        SVGConstants.CSS_FONT_FAMILY_PROPERTY, str);
1814:            }
1815:
1816:            /**
1817:             * Returns a lighter font-weight.
1818:             */
1819:            public float getLighterFontWeight(float f) {
1820:                return userAgent.getLighterFontWeight(f);
1821:            }
1822:
1823:            /**
1824:             * Returns a bolder font-weight.
1825:             */
1826:            public float getBolderFontWeight(float f) {
1827:                return userAgent.getBolderFontWeight(f);
1828:            }
1829:
1830:            /**
1831:             * Returns the size of a px CSS unit in millimeters.
1832:             */
1833:            public float getPixelUnitToMillimeter() {
1834:                return userAgent.getPixelUnitToMillimeter();
1835:            }
1836:
1837:            /**
1838:             * Returns the size of a px CSS unit in millimeters.
1839:             * This will be removed after next release.
1840:             * @see #getPixelUnitToMillimeter()
1841:             */
1842:            public float getPixelToMillimeter() {
1843:                return getPixelUnitToMillimeter();
1844:
1845:            }
1846:
1847:            /**
1848:             * Returns the medium font size.
1849:             */
1850:            public float getMediumFontSize() {
1851:                return userAgent.getMediumFontSize();
1852:            }
1853:
1854:            /**
1855:             * Returns the width of the block which directly contains the
1856:             * given element.
1857:             */
1858:            public float getBlockWidth(Element elt) {
1859:                return getViewport(elt).getWidth();
1860:            }
1861:
1862:            /**
1863:             * Returns the height of the block which directly contains the
1864:             * given element.
1865:             */
1866:            public float getBlockHeight(Element elt) {
1867:                return getViewport(elt).getHeight();
1868:            }
1869:
1870:            /**
1871:             * This method throws a SecurityException if the resource
1872:             * found at url and referenced from docURL
1873:             * should not be loaded.
1874:             *
1875:             * This is a convenience method to call checkLoadExternalResource
1876:             * on the ExternalResourceSecurity strategy returned by
1877:             * getExternalResourceSecurity.
1878:             *
1879:             * @param resourceURL url for the script, as defined in
1880:             *        the resource's xlink:href attribute. If that
1881:             *        attribute was empty, then this parameter should
1882:             *        be null
1883:             * @param docURL url for the document into which the
1884:             *        resource was found.
1885:             */
1886:            public void checkLoadExternalResource(ParsedURL resourceURL,
1887:                    ParsedURL docURL) throws SecurityException {
1888:                userAgent.checkLoadExternalResource(resourceURL, docURL);
1889:            }
1890:
1891:            /**
1892:             * Tells whether the given SVG document is dynamic.
1893:             */
1894:            public boolean isDynamicDocument(Document doc) {
1895:                return BaseScriptingEnvironment.isDynamicDocument(this , doc);
1896:            }
1897:
1898:            /**
1899:             * Tells whether the given SVG document is Interactive.
1900:             * We say it is, if it has any &lt;title>, &lt;desc>, or &lt;a> elements,
1901:             * of if the 'cursor' property is anything but Auto on any element.
1902:             */
1903:            public boolean isInteractiveDocument(Document doc) {
1904:
1905:                Element root = ((SVGDocument) doc).getRootElement();
1906:                if (!SVGConstants.SVG_NAMESPACE_URI.equals(root
1907:                        .getNamespaceURI()))
1908:                    return false;
1909:
1910:                return checkInteractiveElement(root);
1911:            }
1912:
1913:            /**
1914:             * used by isInteractiveDocument to check if document
1915:             * contains any 'interactive' elements.
1916:             */
1917:            public boolean checkInteractiveElement(Element e) {
1918:                return checkInteractiveElement((SVGDocument) e
1919:                        .getOwnerDocument(), e);
1920:            }
1921:
1922:            /**
1923:             * used by isInteractiveDocument to check if document
1924:             * contains any 'interactive' elements.
1925:             */
1926:            public boolean checkInteractiveElement(SVGDocument doc, Element e) {
1927:                String tag = e.getLocalName();
1928:
1929:                // Check if it's one of our important element.
1930:                if (SVGConstants.SVG_A_TAG.equals(tag))
1931:                    return true;
1932:
1933:                // This is a bit of a hack but don't count
1934:                // title and desc as children of root SVG since
1935:                // we don't show tool tips for them anyways.
1936:                if (SVGConstants.SVG_TITLE_TAG.equals(tag)) {
1937:                    return (e.getParentNode() != doc.getRootElement());
1938:                }
1939:                if (SVGConstants.SVG_DESC_TAG.equals(tag)) {
1940:                    return (e.getParentNode() != doc.getRootElement());
1941:                }
1942:                if (SVGConstants.SVG_CURSOR_TAG.equals(tag))
1943:                    return true;
1944:
1945:                // I am well aware that this is not 100% accurate but it's
1946:                // the best I can do w/o booting the CSSEngine.
1947:                if (e.getAttribute(CSSConstants.CSS_CURSOR_PROPERTY).length() > 0)
1948:                    return true;
1949:
1950:                /* We would like to do this but the CSS Engine isn't setup when
1951:                   we want to do this.
1952:
1953:                // Check if cursor property is set to something other than 'auto'.
1954:                Value cursorValue = CSSUtilities.getComputedStyle
1955:                    (e, SVGCSSEngine.CURSOR_INDEX);
1956:                if ((cursorValue != null) &&
1957:                    (cursorValue.getCssValueType()  == CSSValue.CSS_PRIMITIVE_VALUE) &&
1958:                    (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) &&
1959:                    (SVGConstants.SVG_AUTO_VALUE.equals(cursorValue.getStringValue())))
1960:                    return true;
1961:                 */
1962:
1963:                // Check all the child elements for any of the above.
1964:                final String svg_ns = SVGConstants.SVG_NAMESPACE_URI;
1965:                for (Node n = e.getFirstChild(); n != null; n = n
1966:                        .getNextSibling()) {
1967:                    if (n.getNodeType() == Node.ELEMENT_NODE) {
1968:                        Element child = (Element) n;
1969:                        if (svg_ns.equals(child.getNamespaceURI()))
1970:                            if (checkInteractiveElement(child))
1971:                                return true;
1972:                    }
1973:                }
1974:                return false;
1975:            }
1976:
1977:            /**
1978:             * Sets the animation limiting mode to "none".
1979:             */
1980:            public void setAnimationLimitingNone() {
1981:                animationLimitingMode = 0;
1982:                if (animationEngine != null) {
1983:                    setAnimationLimitingMode();
1984:                }
1985:            }
1986:
1987:            /**
1988:             * Sets the animation limiting mode to a percentage of CPU.
1989:             * @param pc the maximum percentage of CPU to use (0 &lt; pc ≤ 1)
1990:             */
1991:            public void setAnimationLimitingCPU(float pc) {
1992:                animationLimitingMode = 1;
1993:                animationLimitingAmount = pc;
1994:                if (animationEngine != null) {
1995:                    setAnimationLimitingMode();
1996:                }
1997:            }
1998:
1999:            /**
2000:             * Sets the animation limiting mode to a number of frames per second.
2001:             * @param fps the maximum number of frames per second (fps &gt; 0)
2002:             */
2003:            public void setAnimationLimitingFPS(float fps) {
2004:                animationLimitingMode = 2;
2005:                animationLimitingAmount = fps;
2006:                if (animationEngine != null) {
2007:                    setAnimationLimitingMode();
2008:                }
2009:            }
2010:
2011:            /**
2012:             * Set the animationg limiting mode on the animation engine.
2013:             */
2014:            protected void setAnimationLimitingMode() {
2015:                switch (animationLimitingMode) {
2016:                case 0: // unlimited
2017:                    animationEngine.setAnimationLimitingNone();
2018:                    break;
2019:                case 1: // %cpu
2020:                    animationEngine
2021:                            .setAnimationLimitingCPU(animationLimitingAmount);
2022:                    break;
2023:                case 2: // fps
2024:                    animationEngine
2025:                            .setAnimationLimitingFPS(animationLimitingAmount);
2026:                    break;
2027:                }
2028:            }
2029:
2030:            // bridge extensions support //////////////////////////////////////////////
2031:
2032:            protected List extensions = null;
2033:
2034:            /**
2035:             * Registers the bridges to handle SVG 1.0 elements.
2036:             */
2037:            public void registerSVGBridges() {
2038:                UserAgent ua = getUserAgent();
2039:                List ext = getBridgeExtensions(document);
2040:                Iterator iter = ext.iterator();
2041:
2042:                while (iter.hasNext()) {
2043:                    BridgeExtension be = (BridgeExtension) iter.next();
2044:                    be.registerTags(this );
2045:                    ua.registerExtension(be);
2046:                }
2047:            }
2048:
2049:            public List getBridgeExtensions(Document doc) {
2050:                Element root = ((SVGOMDocument) doc).getRootElement();
2051:                String ver = root.getAttributeNS(null,
2052:                        SVGConstants.SVG_VERSION_ATTRIBUTE);
2053:                BridgeExtension svgBE;
2054:                if ((ver.length() == 0) || ver.equals("1.0")
2055:                        || ver.equals("1.1"))
2056:                    svgBE = new SVGBridgeExtension();
2057:                else
2058:                    svgBE = new SVG12BridgeExtension();
2059:
2060:                float priority = svgBE.getPriority();
2061:                extensions = new LinkedList(getGlobalBridgeExtensions());
2062:
2063:                ListIterator li = extensions.listIterator();
2064:                for (;;) {
2065:                    if (!li.hasNext()) {
2066:                        li.add(svgBE);
2067:                        break;
2068:                    }
2069:                    BridgeExtension lbe = (BridgeExtension) li.next();
2070:                    if (lbe.getPriority() > priority) {
2071:                        li.previous();
2072:                        li.add(svgBE);
2073:                        break;
2074:                    }
2075:                }
2076:
2077:                return extensions;
2078:            }
2079:
2080:            /**
2081:             * Returns the extensions supported by this bridge context.
2082:             */
2083:            protected static List globalExtensions = null;
2084:
2085:            public static synchronized List getGlobalBridgeExtensions() {
2086:                if (globalExtensions != null) {
2087:                    return globalExtensions;
2088:                }
2089:                globalExtensions = new LinkedList();
2090:
2091:                Iterator iter = Service.providers(BridgeExtension.class);
2092:
2093:                while (iter.hasNext()) {
2094:                    BridgeExtension be = (BridgeExtension) iter.next();
2095:                    float priority = be.getPriority();
2096:                    ListIterator li = globalExtensions.listIterator();
2097:                    for (;;) {
2098:                        if (!li.hasNext()) {
2099:                            li.add(be);
2100:                            break;
2101:                        }
2102:                        BridgeExtension lbe = (BridgeExtension) li.next();
2103:                        if (lbe.getPriority() > priority) {
2104:                            li.previous();
2105:                            li.add(be);
2106:                            break;
2107:                        }
2108:                    }
2109:                }
2110:                return globalExtensions;
2111:            }
2112:
2113:            public static class CSSEngineUserAgentWrapper implements 
2114:                    CSSEngineUserAgent {
2115:                UserAgent ua;
2116:
2117:                CSSEngineUserAgentWrapper(UserAgent ua) {
2118:                    this .ua = ua;
2119:                }
2120:
2121:                /**
2122:                 * Displays an error resulting from the specified Exception.
2123:                 */
2124:                public void displayError(Exception ex) {
2125:                    ua.displayError(ex);
2126:                }
2127:
2128:                /**
2129:                 * Displays a message in the User Agent interface.
2130:                 */
2131:                public void displayMessage(String message) {
2132:                    ua.displayMessage(message);
2133:                }
2134:            }
2135:
2136:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.