javauis/m2g_qt/javasrc/com/nokia/microedition/m2g/M2GSVGImage.java
changeset 80 d6dafc5d983f
child 87 1627c337e51e
equal deleted inserted replaced
78:71ad690e91f5 80:d6dafc5d983f
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 package com.nokia.microedition.m2g;
       
    19 
       
    20 import java.io.ByteArrayInputStream;
       
    21 import java.io.IOException;
       
    22 import java.io.InputStream;
       
    23 import javax.microedition.m2g.ExternalResourceHandler;
       
    24 import javax.microedition.m2g.SVGImage;
       
    25 import org.w3c.dom.Document;
       
    26 import org.w3c.dom.svg.SVGElement;
       
    27 import org.w3c.dom.DOMException;
       
    28 import com.nokia.microedition.m2g.connection.*;
       
    29 import com.nokia.mj.impl.utils.Logger;
       
    30 import com.nokia.mj.impl.utils.StreamUtils;
       
    31 
       
    32 
       
    33 /*
       
    34  * Image implementation
       
    35  */
       
    36 public class M2GSVGImage
       
    37         extends SVGImage
       
    38 {
       
    39     //--------------------------------------------------
       
    40     // STATIC CONSTANTS
       
    41     //--------------------------------------------------
       
    42     /* Optimization: static finals changed to local variables
       
    43     private static final String NULL_TYPE_ESTR =
       
    44       "The type is null.";
       
    45     private static final String ILLEGAL_VALUS_ESTR =
       
    46       "The x or y values are negative.";
       
    47     private static final String EVENT_TYPE_NOT_SUPPORTED_ESTR =
       
    48       "The event type is not supported.";
       
    49     private static final String INVALID_ELEMENT_ESTR =
       
    50       "Invalid element.";
       
    51     public static final String URI_IS_NULL_ESTR =
       
    52       "The URI is null.";
       
    53     */
       
    54 
       
    55     //--------------------------------------------------
       
    56     //  VARIABLES
       
    57     //--------------------------------------------------
       
    58     M2GDocument iDocument = null;
       
    59     private SVGElement iFocusedNode = null;
       
    60 
       
    61     //--------------------------------------------------
       
    62     //  METHODS
       
    63     //--------------------------------------------------
       
    64     /**
       
    65      * Constructor
       
    66      */
       
    67     M2GSVGImage()
       
    68     {
       
    69         super();
       
    70     }
       
    71 
       
    72     /**
       
    73      * @see javax.microedition.m2g.SVGImage#activate()
       
    74      */
       
    75     public void activate()
       
    76     {
       
    77         SVGElement node = iFocusedNode;
       
    78         while (node != null)
       
    79         {
       
    80             ((M2GDocument)getDocument()).handleEvent(new M2GEvent(
       
    81                         M2GSVGConstants.EVENT_ACTIVATE,
       
    82                         node,
       
    83                         M2GEvent.EVENT_TARGET));
       
    84             node = (SVGElement)node.getParentNode();
       
    85         }
       
    86     }
       
    87 
       
    88     /**
       
    89      * @see javax.microedition.m2g.SVGImage#dispatchMouseEvent()
       
    90      */
       
    91     public void dispatchMouseEvent(String type, int x, int y)
       
    92     {
       
    93         if (type == null || type.equals(""))
       
    94         {
       
    95             Logger.ELOG(Logger.EJavaUI, "dispatchMouseEvent() NullPointerException");
       
    96             throw new NullPointerException(/*SF*/"The type is null."/*SF*/);
       
    97         }
       
    98         if (x < 0 || y < 0)
       
    99         {
       
   100             Logger.ELOG(Logger.EJavaUI,
       
   101                         "dispatchMouseEvent() IllegalArgumentException");
       
   102             throw new IllegalArgumentException(/*SF*/"The x or y values are negative."/*SF*/);
       
   103         }
       
   104         if (!type.equals(M2GSVGConstants.EVENT_CLICK))
       
   105         {
       
   106             Logger.ELOG(Logger.EJavaUI,
       
   107                         "dispatchMouseEvent() DOMException - only click event is supported");
       
   108             throw new DOMException(DOMException.NOT_SUPPORTED_ERR, /*SF*/"The event type is not supported."/*SF*/);
       
   109         }
       
   110         int elementHandle = _dispatchMouseEvent(
       
   111                                 iDocument.getNativeSVGProxyHandle(),
       
   112                                 iDocument.getHandle(), x, y);
       
   113 
       
   114         SVGElement targetElement = M2GSVGElement.buildElement(elementHandle, iDocument);
       
   115         SVGElement usedFromElement = null;
       
   116         if ((targetElement != null) && ((M2GSVGElement)targetElement).isUsed())
       
   117         {
       
   118             usedFromElement = ((M2GSVGElement)((M2GSVGElement)targetElement).getUsedFromElement());
       
   119         }
       
   120         if (targetElement instanceof M2GSVGElement)
       
   121         {
       
   122             iFocusedNode = targetElement;
       
   123         }
       
   124         while (targetElement != null)
       
   125         {
       
   126             // click event
       
   127             iDocument.handleEvent(new M2GEvent(
       
   128                                       M2GSVGConstants.EVENT_CLICK, targetElement, M2GEvent.EVENT_TARGET));
       
   129             // DOMActivate event
       
   130             iDocument.handleEvent(new M2GEvent(
       
   131                                       M2GSVGConstants.EVENT_ACTIVATE, targetElement, M2GEvent.EVENT_TARGET));
       
   132             // Gets parent node
       
   133             targetElement = (SVGElement)targetElement.getParentNode();
       
   134         }
       
   135         // The "target element" is only a clone. The "used from element" is the actual element.
       
   136         if (usedFromElement != null)
       
   137         {
       
   138             iDocument.handleEvent(new M2GEvent(
       
   139                                       M2GSVGConstants.EVENT_CLICK, usedFromElement, M2GEvent.WRAPPED_EVENT_TARGET));
       
   140             iDocument.handleEvent(new M2GEvent(
       
   141                                       M2GSVGConstants.EVENT_ACTIVATE, usedFromElement, M2GEvent.WRAPPED_EVENT_TARGET));
       
   142         }
       
   143     }
       
   144 
       
   145     /**
       
   146      * @see javax.microedition.m2g.SVGImage#focusOn()
       
   147      */
       
   148     public void focusOn(SVGElement element)
       
   149     {
       
   150         SVGElement tempNode = element;
       
   151         // If focusOn is called on the same element, do not focus out.
       
   152         boolean callFocusOut =
       
   153             (((iFocusedNode != null) && (iFocusedNode == element ? false : true)) || ((iFocusedNode != null) && (element == null)));
       
   154         //Checking to see if the element is hooked into the tree.
       
   155         if (element != null)
       
   156         {
       
   157             tempNode = element;
       
   158             while (tempNode != null)
       
   159             {
       
   160                 if ((tempNode.getLocalName()).equals(M2GSVGConstants.ROOT_SVG_ELEMENT_NAME))
       
   161                 {
       
   162                     // Breaks if tempNode is root svg
       
   163                     break;
       
   164                 }
       
   165                 tempNode = (SVGElement)tempNode.getParentNode();
       
   166             }
       
   167             // This indicates that the element does not contain a root element,
       
   168             // therefore does not belong to the document.
       
   169             if (tempNode == null)
       
   170             {
       
   171                 Logger.ELOG(Logger.EJavaUI, "focusOn() - DOMException invalid element");
       
   172                 throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, /*SF*/"Invalid element."/*SF*/);
       
   173             }
       
   174         }
       
   175         // Focus out from the current focused node and its parents
       
   176         if (callFocusOut)
       
   177         {
       
   178             if (iFocusedNode instanceof M2GSVGElement)
       
   179             {
       
   180                 _focusOut(
       
   181                     ((M2GSVGElement)iFocusedNode).getNativeSVGProxyHandle(),
       
   182                     ((M2GSVGElement)iFocusedNode).getDocument().getHandle(),
       
   183                     ((M2GSVGElement)iFocusedNode).getHandle());
       
   184             }
       
   185 
       
   186             // Focus out the current focused node and its parents
       
   187             tempNode = iFocusedNode;
       
   188             while (tempNode != null)
       
   189             {
       
   190                 iDocument.handleEvent(new M2GEvent(
       
   191                                           M2GSVGConstants.EVENT_FOCUS_OUT, tempNode, M2GEvent.EVENT_TARGET));
       
   192                 tempNode = (SVGElement)tempNode.getParentNode();
       
   193             }
       
   194         }
       
   195         //focus in for element and its parents
       
   196         if ((element != null) && (element instanceof M2GSVGElement))
       
   197         {
       
   198             _focusOn(
       
   199                 ((M2GSVGElement)element).getNativeSVGProxyHandle(),
       
   200                 ((M2GSVGElement)element).getDocument().getHandle(),
       
   201                 ((M2GSVGElement)element).getHandle() );
       
   202         }
       
   203         tempNode = element;
       
   204         while (tempNode != null)
       
   205         {
       
   206             iDocument.handleEvent(new M2GEvent(
       
   207                                       M2GSVGConstants.EVENT_FOCUS_IN, tempNode, M2GEvent.EVENT_TARGET));
       
   208             tempNode = (SVGElement)tempNode.getParentNode();
       
   209         }
       
   210         // Sets the new focus
       
   211         iFocusedNode = element;
       
   212     }
       
   213 
       
   214     /**
       
   215      * @see javax.microedition.m2g.SVGImage#getDocument()
       
   216      */
       
   217     public Document getDocument()
       
   218     {
       
   219         return iDocument;
       
   220     }
       
   221 
       
   222     /**
       
   223      * @see javax.microedition.m2g.ScalableImage#getViewportHeight()
       
   224      */
       
   225     public synchronized int getViewportHeight()
       
   226     {
       
   227         return iDocument.getViewportHeight();
       
   228     }
       
   229 
       
   230 
       
   231     /*
       
   232      * @see javax.microedition.m2g.ScalableImage#getViewportWidth()
       
   233      */
       
   234     public synchronized int getViewportWidth()
       
   235     {
       
   236         return iDocument.getViewportWidth();
       
   237     }
       
   238 
       
   239     /**
       
   240      * @see javax.microedition.m2g.SVGImage#incrementTime()
       
   241      */
       
   242     public void incrementTime(float seconds)
       
   243     {
       
   244         ((M2GSVGSVGElement)iDocument.getDocumentElement()).incrementTime(seconds);
       
   245     }
       
   246 
       
   247     /**
       
   248      * @see javax.microedition.m2g.ScalableImage#requestCompleted()
       
   249      */
       
   250     public void requestCompleted(String uri, InputStream resourceData) throws IOException
       
   251     {
       
   252         if (uri == null)
       
   253         {
       
   254             Logger.ELOG(Logger.EJavaUI,
       
   255                         "requestCompleted() throw NullPointerException");
       
   256             throw new NullPointerException(/*SF*/"The URI is null."/*SF*/);
       
   257         }
       
   258 
       
   259         if (resourceData != null)
       
   260         {
       
   261             byte receiveData[] = StreamUtils.readBytesFromStream(resourceData, -1);
       
   262             iDocument.requestCompleted(uri, receiveData);
       
   263         }
       
   264         else
       
   265         {
       
   266             // Indicates that the requested resource could not be
       
   267             // fetched by the ResourceHandler or application,
       
   268             // and in this event the SVG engine will not make further attempts
       
   269             // to load this resource.
       
   270             // Pass the null to the native side so it can delete the image
       
   271             iDocument.requestCompleted(uri, null);
       
   272         }
       
   273     }
       
   274 
       
   275     /**
       
   276      * Set document
       
   277      * @param aDocument -
       
   278      */
       
   279     public void setDocument(M2GDocument aDocument)
       
   280     {
       
   281         iDocument = aDocument;
       
   282     }
       
   283 
       
   284     /**
       
   285      * @see javax.microedition.m2g.ScalableImage#setViewportHeight()
       
   286      */
       
   287     public synchronized void setViewportHeight(int height)
       
   288     {
       
   289         iDocument.setViewportHeight(height);
       
   290     }
       
   291 
       
   292     /**
       
   293      * @see javax.microedition.m2g.ScalableImage#setViewportWidth()
       
   294      */
       
   295     public synchronized void setViewportWidth(int width)
       
   296     {
       
   297         iDocument.setViewportWidth(width);
       
   298     }
       
   299 
       
   300     //--------------------------------------------------
       
   301     //  STATIC METHODS
       
   302     //--------------------------------------------------
       
   303     /*
       
   304      * @see javax.microedition.m2g.SVGImage#createEmptyImage()
       
   305      */
       
   306     public static M2GSVGImage buildEmptyImage(ExternalResourceHandler handler)
       
   307     {
       
   308         try
       
   309         {
       
   310             return M2GSVGImage.buildImage(
       
   311                        new ByteArrayInputStream(
       
   312                            M2GSVGConstants.getInstance().iEmptySvgDocument.getBytes()),
       
   313                        handler, null, null);
       
   314         }
       
   315         catch (IOException e)
       
   316         {
       
   317             Logger.ELOG(Logger.EJavaUI, "M2GSVGImage: buildEmptyImage - IOEception: " + e.toString());
       
   318         }
       
   319         return null;
       
   320     }
       
   321 
       
   322     /**
       
   323      * Build svg image
       
   324      * @see javax.microedition.m2g.ScalableImage#createImage()
       
   325      * @param stream Plain text stream that contains svg data
       
   326      * @param handler External resource handler. If null then default
       
   327      * external resource handler is used.
       
   328      * @param baseUrl A base url from where a document is downloaded.
       
   329      * @param suffixUrl The suffix url according to the DRM opening mode of the SVG file
       
   330      * Null if it's not known.
       
   331      */
       
   332     public static M2GSVGImage buildImage(
       
   333         InputStream stream,
       
   334         ExternalResourceHandler handler,
       
   335         String baseUrl,
       
   336         String suffixUrl) throws IOException
       
   337     {
       
   338         if (stream == null)
       
   339         {
       
   340             throw new NullPointerException();
       
   341         }
       
   342 				
       
   343 
       
   344         String strData = new String(StreamUtils.readBytesFromStream(stream, -1));
       
   345 
       
   346         // Default handler is used if the specified handler is null
       
   347         if (handler == null)
       
   348         {
       
   349             handler = M2GConnectionFactory.getExternalResourceHandler(null);
       
   350         }
       
   351 
       
   352         // Creates and setups svg image
       
   353         M2GSVGImage image = new M2GSVGImage();
       
   354         
       
   355         M2GDocument document = M2GDocument.buildDocument(
       
   356                                    image,
       
   357                                    baseUrl,
       
   358                                    suffixUrl,
       
   359                                    strData,
       
   360                                    handler);
       
   361         // Checks document validity
       
   362 				
       
   363         image.setDocument(document);
       
   364         
       
   365         if (handler != null)
       
   366         {
       
   367             // Gets size of external resources
       
   368             int itemCount = _getExternalListSize(
       
   369                                 document.getNativeSVGProxyHandle(),
       
   370                                 document.getHandle());
       
   371 
       
   372             // Loops through external items
       
   373             for (int index = 0; index < itemCount; index++)
       
   374             {
       
   375                 String url = _getExternalListItem(
       
   376                                  document.getNativeSVGProxyHandle(),
       
   377                                  document.getHandle(),
       
   378                                  index);
       
   379                 // Calls an external implementation of the resource handler
       
   380                 if ((url != null) && !(url.equals("")))
       
   381                 {
       
   382                     document.invokeResourceHandler(url);
       
   383                 }
       
   384             }
       
   385         }
       
   386         
       
   387         // initialise the viewport
       
   388         _initViewport(document.getNativeSVGProxyHandle(),
       
   389                       document.getHandle());
       
   390         
       
   391 
       
   392         return image;
       
   393     }
       
   394 
       
   395     /**
       
   396      * @see javax.microedition.m2g.ScalableImage#createImage()
       
   397      */
       
   398     public static M2GSVGImage buildImage(
       
   399         String url, ExternalResourceHandler handler) throws IOException
       
   400     {
       
   401         // Checks passed parameters
       
   402         if (url == null)
       
   403         {
       
   404             Logger.ELOG(Logger.EJavaUI,
       
   405                         "M2GSVGImage: 2 buildImage() - url is null");
       
   406             throw new NullPointerException();
       
   407         }
       
   408         if (url.length() == 0)
       
   409         {
       
   410             Logger.ELOG(Logger.EJavaUI,
       
   411                         "M2GSVGImage: 2 buildImage() - url is empty");
       
   412             throw new IllegalArgumentException();
       
   413         }
       
   414         // Default handler is used if the specified handler is null
       
   415         if (handler == null)
       
   416         {
       
   417             handler = M2GConnectionFactory.getExternalResourceHandler(url);
       
   418         }
       
   419 
       
   420         // Open the url and get input stream
       
   421         M2GSVGImage image = null;
       
   422         M2GConnectionProxy connectionProxy = null;
       
   423         try
       
   424         {
       
   425             connectionProxy = M2GConnectionFactory.create(url);
       
   426             image = M2GSVGImage.buildImage(
       
   427                         connectionProxy.getInputStream(),
       
   428                         handler,
       
   429                         connectionProxy.getBaseUrl(),
       
   430                         connectionProxy.getSuffixUrl());
       
   431             // Set connection policy
       
   432             if (image != null)
       
   433             {
       
   434                 Document doc = image.getDocument();
       
   435                 if (doc != null)
       
   436                 {
       
   437                     ((M2GDocument)doc).setConnectionPolicy(
       
   438                         connectionProxy.getConnectionPolicy());
       
   439                 }
       
   440             }
       
   441             return image;
       
   442         }
       
   443         finally
       
   444         {
       
   445             if (connectionProxy != null)
       
   446             {
       
   447                 connectionProxy.close();
       
   448                 connectionProxy = null;
       
   449             }
       
   450         }
       
   451     }
       
   452 
       
   453     //--------------------------------------------------
       
   454     // NATIVE METHODS
       
   455     //--------------------------------------------------
       
   456     private native static int _dispatchMouseEvent(
       
   457         int aSvgProxyHandle,int aDocumentHandle, 
       
   458         int aX, int aY);
       
   459 
       
   460     private native static void _focusOn(
       
   461         int aSvgProxyHandle,int aDocumentHandle, 
       
   462         int aSvgElementHandle);
       
   463 
       
   464     private native static void _focusOut(
       
   465         int aSvgProxyHandle,int aDocumentHandle, 
       
   466         int aSvgElementHandle);
       
   467 
       
   468     native static int _getExternalListSize(
       
   469          int aSvgProxyHandle, int aDocumentHandle);
       
   470 
       
   471     native static String _getExternalListItem(
       
   472         int aSvgProxyHandle, int aDocumentHandle,
       
   473         int aIndex);
       
   474 
       
   475     private native static void _initViewport(
       
   476         int aSvgProxyHandle, int aDocumentHandle);
       
   477 }