All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.html.geo.spi.GLProvider Maven / Gradle / Ivy

The newest version!
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.netbeans.html.geo.spi;

import net.java.html.BrwsrCtx;
import net.java.html.geo.Position;
import net.java.html.geo.Position.Handle;
import net.java.html.geo.Position.Coordinates;
import org.netbeans.html.context.spi.Contexts.Builder;
import org.netbeans.html.geo.impl.Accessor;
import org.openide.util.lookup.ServiceProvider;

/** SPI for those who wish to provide their own way of obtaining geolocation.
 * Subclass this class, implement its method and register it into the system.
 * You can either use {@link ServiceProvider} to register globally, or 
 * one can register into {@link BrwsrCtx} (via 
 * {@link Builder#register(java.lang.Class, java.lang.Object, int) context builder}).
 * 

* There is default system provider (used as a fallback) based on * * W3C's Geolocation specification - if you are running inside a * browser that supports such standard and you are satisfied with its * behavior, you don't have to register anything. *

* The provider serves two purposes: *

    *
  1. * It handles a geolocation request and creates a "watch" to represent it - * to do so implement the {@link #start(org.netbeans.html.geo.spi.GLProvider.Query) start} * method and the {@link #stop(java.lang.Object) stop} method. *
  2. *
  3. * Once the location is found, the provider needs to * {@link #callback(org.netbeans.html.geo.spi.GLProvider.Query, long, java.lang.Object, java.lang.Exception) call back} * with appropriate location information which can be extracted * later via {@link #latitude(java.lang.Object)} {@link #longitude(java.lang.Object)}, and * other methods in this that also need to be implemented. *
  4. *
*

* The provider is based on a * singletonizer * pattern (applied twice) * and as such one is only required to subclass just the {@link GLProvider} * and otherwise has freedom choosing what classes to use * to represent coordinates and watches. For example if it is enough to use * an array for coordinates and a long number for a watch, one can do: *

 * public final class MyGeoProvider extends {@link GLProvider}<Double[], Long> {
 *   // somehow implement the methods
 * }
 * 
* * @author Jaroslav Tulach * @param your chosen type to represent one query (one time) or watch (repeated) request - * this type is used in {@link #start(org.netbeans.html.geo.spi.GLProvider.Query) start} * and {@link #stop(java.lang.Object) stop} methods. * * @param your chosen type to represent geolocation coordinates - * use in many methods in this class like {@link #latitude(java.lang.Object)} and * {@link #longitude(java.lang.Object)}. * * @since 1.0 */ public abstract class GLProvider { static { Accessor initChannel = new Accessor(false) { @Override public Watch start(GLProvider p, Accessor peer, boolean oneTime, boolean enableHighAccuracy, long timeout, long maximumAge) { return p.start(new Query(peer, oneTime, enableHighAccuracy, timeout, maximumAge)); } @Override public void stop(GLProvider p, Watch w) { p.stop(w); } @Override public void onError(Exception ex) { throw new UnsupportedOperationException(); } @Override public void onLocation(Position position) { throw new UnsupportedOperationException(); } }; } /** Start obtaining geolocation. * When the client {@link Handle#start() requests location} (and * your provider is found) this method should initialize the request or * return null to give chance to another provider. * * @param c the query describing the request and * to {@link #callback(org.netbeans.html.geo.spi.GLProvider.Query, long, java.lang.Object, java.lang.Exception) use when location is found} - * keep it, you'll need it later * * @return an object representing the request (so it can be {@link #stop(java.lang.Object) stopped} later) * or null if this provider was unable to start the request */ protected abstract Watch start(Query c); /** Called when a geolocation request should be stopped. * * @param watch the watch returned when {@link #start(org.netbeans.html.geo.spi.GLProvider.Query) starting} * the request */ protected abstract void stop(Watch watch); /** Invoke this method when your provider obtained requested location. * This single method is used for notification of success (when ex * argument is null and position is provided) or * a failure (when ex argument is non-null). * A successful requests leads in a call to {@link Handle#onLocation(net.java.html.geo.Position)} * while an error report leads to a call to {@link Handle#onError(java.lang.Exception)}. * The actual call is sent to {@link BrwsrCtx#execute(java.lang.Runnable)} of * context recorded when the {@link Query} was created to guarantee it * happens on the right browser thread - however it may happen "later" * when this method has already finished. * * @param c the query as provided when {@link #start(org.netbeans.html.geo.spi.GLProvider.Query) starting} * the request * @param timestamp milliseconds since epoch when the location has been obtained * @param position your own, internal, representation of geolocation * coordinates - will be passed back to other methods of this class * like {@link #latitude(java.lang.Object)} and {@link #longitude(java.lang.Object)}. * Can be null if ex is non-null * @param ex an exception to signal an error - should be null * when one notifies the successfully obtained position */ protected final void callback( final Query c, final long timestamp, final Coords position, final Exception ex ) { c.ctx.execute(new Runnable() { @Override public void run() { if (ex == null) { c.peer.onLocation(new Position(timestamp, new CoordImpl(position, GLProvider.this))); } else { c.peer.onError(ex); } } }); } /** Extracts value for {@link Coordinates#getLatitude()}. * @param coords your own internal representation of coordinates. * @return geographic coordinate specified in decimal degrees. */ protected abstract double latitude(Coords coords); /** Extracts value for {@link Coordinates#getLatitude()}. * @param coords your own internal representation of coordinates. * @return geographic coordinate specified in decimal degrees. */ protected abstract double longitude(Coords coords); /** Extracts value for {@link Coordinates#getLatitude()}. * The accuracy attribute denotes the accuracy level of the latitude * and longitude coordinates. * * @param coords your own internal representation of coordinates. * @return accuracy in meters */ protected abstract double accuracy(Coords coords); /** Extracts value for {@link Coordinates#getAltitude()}. * Denotes the height of the position, specified in meters above the ellipsoid. * * @param coords your own internal representation of coordinates. * @return value in meters, may return null, if the information is not available */ protected abstract Double altitude(Coords coords); /** Extracts value for {@link Coordinates#getAltitudeAccuracy()} - * the altitude accuracy is specified in meters. * * @param coords your own internal representation of coordinates. * @return value in meters; may return null, if the information is not available */ protected abstract Double altitudeAccuracy(Coords coords); /** Extracts value for {@link Coordinates#getHeading()}. * Denotes the magnitude of the horizontal component of the * device's current velocity and is specified in meters per second. * * @param coords your own internal representation of coordinates. * @return may return null, if the information is not available */ protected abstract Double heading(Coords coords); /** Extracts value for {@link Coordinates#getSpeed()}. * Denotes the magnitude of the horizontal component of the * device's current velocity and is specified in meters per second. * * @param coords your own internal representation of coordinates. * @return may return null, if the information is not available */ protected abstract Double speed(Coords coords); /** Holds parameters describing the location query and is used by {@link GLProvider} to notify back * results of its findings. */ public static final class Query { private final boolean oneTime; private final boolean enableHighAccuracy; private final long timeout; private final long maximumAge; private final BrwsrCtx ctx; final Accessor peer; Query(Accessor peer, boolean oneTime, boolean enableHighAccuracy, long timeout, long maximumAge) { this.peer = peer; this.oneTime = oneTime; this.enableHighAccuracy = enableHighAccuracy; this.timeout = timeout; this.maximumAge = maximumAge; ctx = BrwsrCtx.findDefault(Query.class); } /** * Is this one time or repeated request? Mimics value provided in * {@link Handle constructor}. * * @return true if this is one time request, false if the request is * permanent (up until {@link Handle#stop() } is called). */ public final boolean isOneTime() { return oneTime; } /** * Turns on high accuracy mode as specified by the * * W3C's Geolocation API. By default the mode is disabled. Mimics * value of {@link Handle#setHighAccuracy(boolean)}. * * @return enable true or false */ public final boolean isHighAccuracy() { return this.enableHighAccuracy; } /** * The amount of milliseconds to wait for a result. Mimics value of * {@link Handle#setTimeout(long)}. * * @return time in milliseconds to wait for a result. */ public final long getTimeout() { return this.timeout; } /** * Sets maximum age of cached results which are acceptable to be * returned. Mimics value of {@link Handle#setMaximumAge(long)}. * * @return time in milliseconds of acceptable cached results */ public final long getMaximumAge() { return this.maximumAge; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy