![JAR search and dependency download from the Maven repository](/logo.png)
it.tidalwave.geo.location.elmo.impl.ElmoGeoLocation Maven / Gradle / Ivy
/***********************************************************************************************************************
*
* forceTen - open source geography
* Copyright (C) 2007-2012 by Tidalwave s.a.s. (http://www.tidalwave.it)
*
***********************************************************************************************************************
*
* Licensed 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.
*
***********************************************************************************************************************
*
* WWW: http://forceten.tidalwave.it
* SCM: https://bitbucket.org/tidalwave/forceten-src
*
**********************************************************************************************************************/
package it.tidalwave.geo.location.elmo.impl;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import org.openide.util.Parameters;
import org.openrdf.elmo.annotations.rdf;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.util.DuplicateException;
import it.tidalwave.util.NotFoundException;
import it.tidalwave.semantic.LazyPropertyHolder;
import it.tidalwave.semantic.Wrapper;
import it.tidalwave.openrdf.elmo.ElmoUtils;
import it.tidalwave.openrdf.elmo.ElmoVolatile;
import it.tidalwave.geo.Coordinate;
import it.tidalwave.geo.geocoding.GeoCoderEntity.Type;
import it.tidalwave.geo.location.GeoLocation;
import it.tidalwave.geo.location.GeoPath;
import it.tidalwave.geo.location.GeoSchema;
import it.tidalwave.geo.location.elmo.GeoVocabulary;
import static it.tidalwave.semantic.SkosConcept.SkosConcept;
import static it.tidalwave.geo.location.GeoLocation.GeoLocation;
import static it.tidalwave.role.MutableDisplayable.MutableDisplayable;
/***********************************************************************************************************************
*
* @author Fabrizio Giudici
* @version $Id$
*
**********************************************************************************************************************/
@rdf(GeoVocabulary.URI_GEO_LOCATION)
public class ElmoGeoLocation extends Support implements GeoLocation
{
private final static String CLASS = ElmoGeoLocation.class.getName();
private final static Logger logger = Logger.getLogger(CLASS);
/** Only used by instances not backed by a {@link GeoCoderEntityProxy}, otherwise delegates to it. */
@CheckForNull @rdf(GeoVocabulary.URI_WGS84_LATITUDE)
private Double latitude;
/** Only used by instances not backed by a {@link GeoCoderEntityProxy}, otherwise delegates to it. */
@CheckForNull @rdf(GeoVocabulary.URI_WGS84_LONGITUDE)
private Double longitude;
/** Only used by instances not backed by a {@link GeoCoderEntityProxy}, otherwise delegates to it. */
@CheckForNull @rdf(GeoVocabulary.URI_WGS84_ALTITUDE)
private Double altitude;
/** Only used by instances not backed by a {@link GeoCoderEntityProxy}, otherwise delegates to it. */
@CheckForNull @rdf(GeoVocabulary.URI_CODE)
private String code;
/*******************************************************************************************************************
*
* Only used by instances not backed by a {@link GeoCoderEntityProxy}, otherwise delegates to it.
*
******************************************************************************************************************/
@ElmoVolatile
private final LazyPropertyHolder coordinateHolder = new LazyPropertyHolder()
{
@Override @CheckForNull
protected Coordinate create()
{
if ((latitude != null) && (longitude != null))
{
return (altitude != null) ? new Coordinate(latitude, longitude, altitude)
: new Coordinate(latitude, longitude);
}
return null;
}
};
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public Object findType (final @Nonnull GeoSchema geoSchema)
{
try
{
Parameters.notNull("geoSchema", geoSchema);
logger.fine("findType(%s) - %s", geoSchema, this);
return findGeoCoderEntityProxy(geoSchema).getType();
}
catch (NotFoundException e)
{
return Type.UNKNOWN;
}
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public String findCode (final @Nonnull GeoSchema geoSchema)
{
try
{
Parameters.notNull("geoSchema", geoSchema);
logger.fine("findCode(%s) - %s", geoSchema, this);
return findGeoCoderEntityProxy(geoSchema).getCode();
}
catch (NotFoundException e)
{
return (code != null) ? code : "";
}
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public Coordinate findCoordinate (final @Nonnull GeoSchema geoSchema)
throws NotFoundException
{
try
{
Parameters.notNull("geoSchema", geoSchema);
logger.fine("findCoordinate(%s) - %s", geoSchema, this);
return findGeoCoderEntityProxy(geoSchema).getCoordinate();
}
catch (NotFoundException e)
{
return NotFoundException.throwWhenNull(coordinateHolder.get(), "No coordinates for " + this);
}
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public GeoLocation findParent (final @Nonnull GeoSchema geoSchema)
throws NotFoundException
{
Parameters.notNull("geoSchema", geoSchema);
logger.fine("findParent(%s) - %s", geoSchema, this);
GeoCoderEntityProxy gcEntityProxy = null;
try
{
gcEntityProxy = findGeoCoderEntityProxy(geoSchema);
// Don't put geoNode.getParent() from the last return line here, since it can throw NotFoundException as
// well and that must be thrown. Here we must catch NotFoundException only from findGeoNode()
}
catch (NotFoundException e)
{
return as(SkosConcept).findBroaders().ofType(GeoLocation).result();
}
return ElmoGeoLocationFactory.findOrCreate(geoSchema, gcEntityProxy.getParent());
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public Finder findChildren (final @Nonnull GeoSchema geoSchema)
{
Parameters.notNull("geoSchema", geoSchema);
logger.fine("findChildren(%s) - %s", geoSchema, this);
return new FinderSupport(String.format("findChildren(%s)", geoSchema))
{
@Override
@Nonnull
protected List computeResults()
{
final List gcEntityProxyChildren = new ArrayList();
try
{
final GeoCoderEntityProxy gcEntityProxy = findGeoCoderEntityProxy(geoSchema);
//
// Different strategies because when a condition is specified we don't want to bring all the
// children into the repository.
//
if (displayName == null)
{
gcEntityProxyChildren.addAll(gcEntityProxy.getChildren());
}
else
{
gcEntityProxyChildren.add(gcEntityProxy.findChildByName(displayName));
}
}
catch (NotFoundException e)
{
doNothing(); // just return an empty list
}
final List result = new ArrayList();
for (final GeoCoderEntityProxy gcEntityProxy : gcEntityProxyChildren)
{
result.add(ElmoGeoLocationFactory.findOrCreate(geoSchema, gcEntityProxy));
}
// FIXME: add children in the local repo (e.g. Polanesi in the test)
return Wrapper.wrap(result);
}
};
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public Builder createChild()
{
return new Builder()
{
@Override
public GeoLocation build()
throws DuplicateException
{
final GeoLocation child = ElmoGeoLocationFactory.findOrCreate(null, null);
child.as(MutableDisplayable).setDisplayNames(displayNames);
if (coordinate != null)
{
child.setCoordinate(coordinate);
}
if (code != null)
{
child.setCode(code);
}
// TODO: type
merge(child);
ElmoGeoLocation.this.as(SkosConcept).addNarrower(child);
return child;
}
};
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public GeoPath findPath (@Nonnull GeoSchema geoSchema)
{
Parameters.notNull("geoSchema", geoSchema);
logger.fine("findPath(%s)", geoSchema);
final List result = new ArrayList();
try
{
result.addAll(findParent(geoSchema).findPath(geoSchema).asList());
}
catch (NotFoundException e)
{
doNothing(); // ok, reached the root
}
// GeoPath is not automatically proxied, so we must manually wrap
// We could perhaps annotate non-entity classes for having them auto-wrapped?
result.add(Wrapper.wrap(this));
final ElmoGeoPath path = new ElmoGeoPath(result);
logger.finer(">>>> returning %s", path);
return path;
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void setCoordinate (final @Nonnull Coordinate coordinate)
{
Parameters.notNull("coordinate", coordinate);
// FIXME: throw IllegalStateException if this object is bound to a GeoCoderEntityProxy.
this.latitude = coordinate.getLatitude();
this.longitude = coordinate.getLongitude();
this.altitude = coordinate.getAltitude();
this.coordinateHolder.invalidate();
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void setCode (final @Nonnull String code)
{
Parameters.notNull("code", code);
// FIXME: throw IllegalStateException if this object is bound to a GeoCoderEntityProxy.
this.code = code;
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public String toString()
{
return String.format("ElmoGeoLocation@%x[%s (%s; %s; %s) code: %s]",
System.identityHashCode(this),
ElmoUtils.toString(this),
latitude, longitude, altitude,
code);
}
/*******************************************************************************************************************
*
* Finds or creates a GeoCoderEntityProxy bound to the current Location according to the given GeoSchema.
*
******************************************************************************************************************/
@Nonnull
private GeoCoderEntityProxy findGeoCoderEntityProxy (final @Nonnull GeoSchema geoSchema)
throws NotFoundException
{
assert geoSchema != null : "null geoSchema";
logger.fine("findGeoCoderEntityProxy(%s)", geoSchema);
// TODO: cache it for the current transaction?
final GeoCoderEntityProxy gcEntityProxy = ElmoGeoCoderEntityProxyFactory.findSame(this, geoSchema);
logger.finer(">>>> returning %s", gcEntityProxy);
return gcEntityProxy;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy