
org.netbeans.html.geo.spi.GLProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of net.java.html.geo Show documentation
Show all versions of net.java.html.geo Show documentation
Find out where your Java program running in an HTML page is!
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:
*
* -
* 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.
*
* -
* 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.
*
*
*
* 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, Watch> 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, Watch> 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