Documenting Geolocation SPI GeoSPI
authorJaroslav Tulach <jtulach@netbeans.org>
Wed, 27 Aug 2014 18:26:43 +0200
branchGeoSPI
changeset 8435ed774012807
parent 842 ebb2428bb7e1
child 844 cdc17834e71c
Documenting Geolocation SPI
geo/pom.xml
geo/src/main/java/net/java/html/geo/Position.java
geo/src/main/java/org/netbeans/html/geo/spi/GLProvider.java
geo/src/main/java/org/netbeans/html/geo/spi/package.html
     1.1 --- a/geo/pom.xml	Wed Aug 27 17:28:30 2014 +0200
     1.2 +++ b/geo/pom.xml	Wed Aug 27 18:26:43 2014 +0200
     1.3 @@ -14,7 +14,7 @@
     1.4    <url>http://maven.apache.org</url>
     1.5    <properties>
     1.6      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     1.7 -    <publicPackages>net.java.html.geo</publicPackages>
     1.8 +    <publicPackages>net.java.html.geo,org.netbeans.html.geo.spi</publicPackages>
     1.9    </properties>
    1.10    <build>
    1.11        <plugins>
     2.1 --- a/geo/src/main/java/net/java/html/geo/Position.java	Wed Aug 27 17:28:30 2014 +0200
     2.2 +++ b/geo/src/main/java/net/java/html/geo/Position.java	Wed Aug 27 18:26:43 2014 +0200
     2.3 @@ -130,10 +130,11 @@
     2.4          public abstract Double getAltitudeAccuracy();
     2.5          
     2.6          /** Denotes the direction of travel of the device and 
     2.7 -         * is specified in degrees, where 0° ≤ heading < 360°, 
     2.8 +         * is specified in degrees 
     2.9           * counting clockwise relative to the true north. 
    2.10           * 
    2.11 -         * @return may return null, if the information is not available 
    2.12 +         * @return value from 0 to 360 - may return <code>null</code>, 
    2.13 +         *   if the information is not available 
    2.14           */
    2.15          public abstract Double getHeading();
    2.16          
     3.1 --- a/geo/src/main/java/org/netbeans/html/geo/spi/GLProvider.java	Wed Aug 27 17:28:30 2014 +0200
     3.2 +++ b/geo/src/main/java/org/netbeans/html/geo/spi/GLProvider.java	Wed Aug 27 18:26:43 2014 +0200
     3.3 @@ -43,20 +43,113 @@
     3.4  
     3.5  package org.netbeans.html.geo.spi;
     3.6  
     3.7 +import net.java.html.BrwsrCtx;
     3.8  import net.java.html.geo.Position;
     3.9 +import org.netbeans.html.context.spi.Contexts;
    3.10 +import org.openide.util.lookup.ServiceProvider;
    3.11  
    3.12 -/**
    3.13 +/** SPI for those who wish to provide their own way of obtaining geolocation.
    3.14 + * Subclass this class, implement its method and register it into the system.
    3.15 + * You can either use {@link ServiceProvider} to register globally, or 
    3.16 + * one can register into {@link BrwsrCtx} (via 
    3.17 + * {@link Contexts.Builder#register(java.lang.Class, java.lang.Object, int) context builder}).
    3.18 + * <p>
    3.19 + * There is default system provider (used as a fallback) based on 
    3.20 + * <a href="http://www.w3.org/TR/geolocation-API/">
    3.21 + * W3C's Geolocation</a> specification - if you are running inside a
    3.22 + * browser that supports such standard and you are satisfied with its
    3.23 + * behavior, you don't have to register anything.
    3.24 + * <p>
    3.25 + * The provider serves two purposes: 
    3.26 + * <ol>
    3.27 + *   <li>
    3.28 + *     It handles a geolocation request and creates a "watch" to represent it -
    3.29 + *     to do so implement the {@link #start(org.netbeans.html.geo.spi.GLProvider.Callback, boolean, boolean, long, long) start} 
    3.30 + *     method and the {@link #stop(java.lang.Object) stop} method.
    3.31 + *   </li>
    3.32 + *   <li>
    3.33 + *     Once the location is found, the provider needs to 
    3.34 + *     {@link #callback(org.netbeans.html.geo.spi.GLProvider.Callback, long, java.lang.Object, java.lang.Exception) call back}
    3.35 + *     with appropriate location information which can be extracted
    3.36 + *     later via {@link #latitude(java.lang.Object)} {@link #longitude(java.lang.Object)}, and
    3.37 + *     other methods in this that also need to be implemented.
    3.38 + *   </li>
    3.39 + * </ol>
    3.40 + * <p>
    3.41 + * The provider is based on a 
    3.42 + * <a href="http://wiki.apidesign.org/wiki/Singletonizer" target="_blank">singletonizer</a> 
    3.43 + * pattern (applied twice)
    3.44 + * and as such one is only required to subclass just the {@link GLProvider} 
    3.45 + * and otherwise has freedom choosing what classes to use
    3.46 + * to represent coordinates and watches. For example if it is enough to use
    3.47 + * an array for coordinates and a long number for a watch, one can do:
    3.48 + * <pre>
    3.49 + * <b>public final class</b> MyGeoProvider extends {@link GLProvider}&lt;Double[], Long&gt; {
    3.50 + *   <em>// somehow implement the methods</em>
    3.51 + * }
    3.52 + * </pre>
    3.53   *
    3.54   * @author Jaroslav Tulach
    3.55 + * @param <Watch> your choosen type to represent one query (one time) or watch (repeated) request -
    3.56 + *   this type is used in {@link #start(org.netbeans.html.geo.spi.GLProvider.Callback, boolean, boolean, long, long) start}
    3.57 + *   and {@link #stop(java.lang.Object) stop} methods.
    3.58 + * 
    3.59 + * @param <Coords> your choosen type to represent geolocation coordinates -
    3.60 + *   use in many methods in this class like {@link #latitude(java.lang.Object)} and
    3.61 + *   {@link #longitude(java.lang.Object)}.
    3.62 + * 
    3.63 + * @since 1.0
    3.64   */
    3.65  public abstract class GLProvider<Coords,Watch> {
    3.66 +    /** Start obtaining geolocation.
    3.67 +     * When the client {@link Position.Handle#start() requests location} (and
    3.68 +     * your provider is found) this method should initialize the request or 
    3.69 +     * return <code>null</code> to give chance to another provider.
    3.70 +     * 
    3.71 +     * @param c the callback to {@link #callback(org.netbeans.html.geo.spi.GLProvider.Callback, long, java.lang.Object, java.lang.Exception) use when location is found} -
    3.72 +     *    keep it, you'll need it later
    3.73 +     * @param oneTime one time request vs. repeated requests
    3.74 +     *    - mimics value provided in {@link Position.Handle#Handle(boolean) constructor}
    3.75 +     * @param enableHighAccuracy mimics value of
    3.76 +     *    {@link Position.Handle#setHighAccuracy(boolean)}
    3.77 +     * @param timeout mimics value of
    3.78 +     *    {@link Position.Handle#setTimeout(long)}
    3.79 +     * @param maximumAge mimics value of 
    3.80 +     *    {@link Position.Handle#setMaximumAge(long)}
    3.81 +     * 
    3.82 +     * @return an object representing the request (so it can be {@link #stop(java.lang.Object) stopped} later)
    3.83 +     *   or <code>null</code> if this provider was unable to start the request
    3.84 +     */
    3.85      protected abstract Watch start(
    3.86          Callback c, 
    3.87          boolean oneTime, boolean enableHighAccuracy, 
    3.88          long timeout, long maximumAge
    3.89      );
    3.90 +    
    3.91 +    /** Called when a geolocation request should be stopped.
    3.92 +     * 
    3.93 +     * @param watch the watch returned when {@link #start(org.netbeans.html.geo.spi.GLProvider.Callback, boolean, boolean, long, long) starting}
    3.94 +     *   the request
    3.95 +     */
    3.96      protected abstract void stop(Watch watch);
    3.97 -    
    3.98 +
    3.99 +    /** Invoke this method when your provider obtained request location.
   3.100 +     * This single method is used for notification of success (when <code>ex</code>
   3.101 +     * argument is <code>null</code> and <code>position</code> is provided) or 
   3.102 +     * a failure (when <code>ex</code> argument is non-<code>null</code>).
   3.103 +     * A successful requests leads in call to {@link Position.Handle#onLocation(net.java.html.geo.Position)}
   3.104 +     * while an error report leads to call to {@link Position.Handle#onError(java.lang.Exception)}.
   3.105 +     * 
   3.106 +     * @param c the callback as provided when {@link #start(org.netbeans.html.geo.spi.GLProvider.Callback, boolean, boolean, long, long) starting}
   3.107 +     *   the request
   3.108 +     * @param timestamp milliseconds since epoch when the location has been obtained
   3.109 +     * @param position your own, internal, representation of geolocation
   3.110 +     *   coordinates - will be passed back to other methods of this class
   3.111 +     *   like {@link #latitude(java.lang.Object)} and {@link #longitude(java.lang.Object)}.
   3.112 +     *   Can be <code>null</code> if <code>ex</code> is non-<code>null</code>
   3.113 +     * @param ex an exception to signal an error - should be <code>null</code>
   3.114 +     *   when one notifies the successfully obtained <code>position</code>
   3.115 +     */
   3.116      protected final void callback(
   3.117          Callback c,
   3.118          long timestamp, Coords position,
   3.119 @@ -68,32 +161,113 @@
   3.120              c.onError(ex);
   3.121          }
   3.122      }
   3.123 +
   3.124 +    /** Extracts value for {@link Position.Coordinates#getLatitude()}.
   3.125 +     * @param coords your own internal representation of coordinates.
   3.126 +     * @return geographic coordinate specified in decimal degrees.
   3.127 +     */
   3.128 +    protected abstract double latitude(Coords coords);
   3.129      
   3.130 -    protected abstract double latitude(Coords coords);
   3.131 +    /** Extracts value for {@link Position.Coordinates#getLatitude()}.
   3.132 +     * @param coords your own internal representation of coordinates.
   3.133 +     * @return geographic coordinate specified in decimal degrees.
   3.134 +     */
   3.135      protected abstract double longitude(Coords coords);
   3.136 +    
   3.137 +    /** Extracts value for {@link Position.Coordinates#getLatitude()}.
   3.138 +     * The accuracy attribute denotes the accuracy level of the latitude 
   3.139 +     * and longitude coordinates.
   3.140 +     * 
   3.141 +     * @param coords your own internal representation of coordinates.
   3.142 +     * @return accuracy in meters
   3.143 +     */
   3.144      protected abstract double accuracy(Coords coords);
   3.145 +    
   3.146 +    /** Extracts value for {@link Position.Coordinates#getAltitude()}.
   3.147 +     * Denotes the height of the position, specified in meters above the ellipsoid.
   3.148 +     * 
   3.149 +     * @param coords your own internal representation of coordinates.
   3.150 +     * @return value in meters, may return null, if the information is not available
   3.151 +     */
   3.152      protected abstract Double altitude(Coords coords);
   3.153 +    
   3.154 +    /** Extracts value for {@link Position.Coordinates#getAltitudeAccuracy()} -
   3.155 +     * the altitude accuracy is specified in meters. 
   3.156 +     * 
   3.157 +     * @param coords your own internal representation of coordinates.
   3.158 +     * @return value in meters; may return null, if the information is not available
   3.159 +     */
   3.160      protected abstract Double altitudeAccuracy(Coords coords);
   3.161 +    
   3.162 +    /** Extracts value for {@link Position.Coordinates#getHeading()}.
   3.163 +     * Denotes the magnitude of the horizontal component of the 
   3.164 +     * device's current velocity and is specified in meters per second.
   3.165 +     * 
   3.166 +     * @param coords your own internal representation of coordinates.
   3.167 +     * @return may return null, if the information is not available 
   3.168 +     */
   3.169      protected abstract Double heading(Coords coords);
   3.170 +    
   3.171 +    /** Extracts value for {@link Position.Coordinates#getSpeed()}.
   3.172 +     * Denotes the magnitude of the horizontal component of the 
   3.173 +     * device's current velocity and is specified in meters per second.
   3.174 +     * 
   3.175 +     * @param coords your own internal representation of coordinates.
   3.176 +     * @return may return null, if the information is not available
   3.177 +     */
   3.178      protected abstract Double speed(Coords coords);
   3.179      
   3.180 -    
   3.181 +    /** A callback interface used by {@link GLProvider} to notify back
   3.182 +     * results of its findings.
   3.183 +     */
   3.184      public static abstract class Callback {
   3.185 +        /** Restricted constructor.
   3.186 +         * @throws IllegalStateException most of the time
   3.187 +         */
   3.188          protected Callback() {
   3.189              if (!getClass().getName().equals("net.java.html.geo.Position$Handle$JsH")) {
   3.190                  throw new IllegalStateException();
   3.191              }
   3.192          }
   3.193 -        
   3.194 +
   3.195 +        /** Initiates a geolocation request. 
   3.196 +         * 
   3.197 +         * @param <Watch> representation of watch as provided by {@link GLProvider}.
   3.198 +         * @param p the provider to ask
   3.199 +         * @param oneTime one time request vs. repeated requests
   3.200 +         *    - mimics value provided in {@link Position.Handle#Handle(boolean) constructor}
   3.201 +         * @param enableHighAccuracy mimics value of
   3.202 +         *    {@link Position.Handle#setHighAccuracy(boolean)}
   3.203 +         * @param timeout mimics value of
   3.204 +         *    {@link Position.Handle#setTimeout(long)}
   3.205 +         * @param maximumAge mimics value of 
   3.206 +         *    {@link Position.Handle#setMaximumAge(long)}
   3.207 +         * @return an object representing the request (so it can be {@link #stop(java.lang.Object) stopped} later)
   3.208 +         *   or <code>null</code> if this provider was unable to start the request
   3.209 +         */
   3.210          protected final <Watch> Watch start(GLProvider<?,Watch> p, boolean oneTime, boolean enableHighAccuracy, long timeout, long maximumAge) {
   3.211              return p.start(this, oneTime, enableHighAccuracy, timeout, maximumAge);
   3.212          }
   3.213 -        
   3.214 +  
   3.215 +        /** Stops the watch request.
   3.216 +         * 
   3.217 +         * @param <Watch> internal type of the watch
   3.218 +         * @param p the provider of the watch
   3.219 +         * @param w the watch
   3.220 +         */
   3.221          protected final <Watch> void stop(GLProvider<?,Watch> p, Watch w) {
   3.222              p.stop(w);
   3.223          }
   3.224          
   3.225 +        /** Called when a position is successfully obtained.
   3.226 +         * 
   3.227 +         * @param p the position
   3.228 +         */
   3.229          protected abstract void onLocation(Position p);
   3.230 +        
   3.231 +        /** Called on an error during obtaining of the position.
   3.232 +         * @param ex exception describing the error
   3.233 +         */
   3.234          protected abstract void onError(Exception ex);
   3.235      }
   3.236  }
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/geo/src/main/java/org/netbeans/html/geo/spi/package.html	Wed Aug 27 18:26:43 2014 +0200
     4.3 @@ -0,0 +1,59 @@
     4.4 +<!--
     4.5 +
     4.6 +    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.7 +
     4.8 +    Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     4.9 +
    4.10 +    Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    4.11 +    Other names may be trademarks of their respective owners.
    4.12 +
    4.13 +    The contents of this file are subject to the terms of either the GNU
    4.14 +    General Public License Version 2 only ("GPL") or the Common
    4.15 +    Development and Distribution License("CDDL") (collectively, the
    4.16 +    "License"). You may not use this file except in compliance with the
    4.17 +    License. You can obtain a copy of the License at
    4.18 +    http://www.netbeans.org/cddl-gplv2.html
    4.19 +    or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    4.20 +    specific language governing permissions and limitations under the
    4.21 +    License.  When distributing the software, include this License Header
    4.22 +    Notice in each file and include the License file at
    4.23 +    nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    4.24 +    particular file as subject to the "Classpath" exception as provided
    4.25 +    by Oracle in the GPL Version 2 section of the License file that
    4.26 +    accompanied this code. If applicable, add the following below the
    4.27 +    License Header, with the fields enclosed by brackets [] replaced by
    4.28 +    your own identifying information:
    4.29 +    "Portions Copyrighted [year] [name of copyright owner]"
    4.30 +
    4.31 +    Contributor(s):
    4.32 +
    4.33 +    The Original Software is NetBeans. The Initial Developer of the Original
    4.34 +    Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    4.35 +
    4.36 +    If you wish your version of this file to be governed by only the CDDL
    4.37 +    or only the GPL Version 2, indicate your decision by adding
    4.38 +    "[Contributor] elects to include this software in this distribution
    4.39 +    under the [CDDL or GPL Version 2] license." If you do not indicate a
    4.40 +    single choice of license, a recipient has the option to distribute
    4.41 +    your version of this file under either the CDDL, the GPL Version 2 or
    4.42 +    to extend the choice of license to its licensees as provided above.
    4.43 +    However, if you add GPL Version 2 code and therefore, elected the GPL
    4.44 +    Version 2 license, then the option applies only if the new code is
    4.45 +    made subject to such option by the copyright holder.
    4.46 +
    4.47 +-->
    4.48 +<!DOCTYPE html>
    4.49 +<html>
    4.50 +    <head>
    4.51 +        <title>Geolocation SPI</title>
    4.52 +        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    4.53 +        <meta name="viewport" content="width=device-width">
    4.54 +    </head>
    4.55 +    <body>
    4.56 +        <div>
    4.57 +            Service provider interfaces for those willing to 
    4.58 +            {@link org.netbeans.html.geo.spi.GLProvider provide their own way}
    4.59 +            of obtaining proper geolocation.
    4.60 +        </div>
    4.61 +    </body>
    4.62 +</html>