X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=gis%2Fruntime%2Forg.argeo.gis.geotools%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fgeotools%2Fjcr%2FSimpleGeoJcrMapper.java;h=27da93738e19fa93a0d816dce153b0664c57fd6f;hb=c3be9f8db8a79e159d6a057758dfc7f3580efc2d;hp=d3661870546011cef32c9434f2afb785f2e6590c;hpb=7fe4a16dad045373bb014724733c1bbb175d44b5;p=lgpl%2Fargeo-commons.git diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java index d36618705..27da93738 100644 --- a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java @@ -18,26 +18,40 @@ import org.argeo.ArgeoException; import org.argeo.geotools.GeoToolsConstants; import org.argeo.geotools.GeoToolsUtils; import org.argeo.jcr.JcrUtils; +import org.argeo.jcr.gis.GisJcrConstants; import org.argeo.jcr.gis.GisNames; import org.argeo.jcr.gis.GisTypes; import org.argeo.jts.jcr.JtsJcrUtils; import org.geotools.data.DataStore; import org.geotools.data.FeatureSource; +import org.geotools.referencing.CRS; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.Name; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; -public class SimpleGeoJcrMapper implements GeoJcrMapper { +/** Maps geographical information meta data in a JCR repository. */ +public class SimpleGeoJcrMapper implements GeoJcrMapper, GisNames { private final static Log log = LogFactory.getLog(SimpleGeoJcrMapper.class); - private String dataStoresBasePath = "/gis/dataStores"; - private Map registeredDataStores = Collections .synchronizedSortedMap(new TreeMap()); - // private Session session; + private Session systemSession; + + public void init() throws RepositoryException { + } + + public void dispose() { + if (systemSession != null) + systemSession.logout(); + } public Map>> getPossibleFeatureSources() { Map>> res = new TreeMap>>(); @@ -102,16 +116,46 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { Node featureNode = featureSourceNode.addNode(featureId); featureNode.addMixin(GisTypes.GIS_FEATURE); Geometry geometry = (Geometry) feature.getDefaultGeometry(); - featureNode.setProperty(GisNames.GIS_SRS, featureSource - .getSchema().getCoordinateReferenceSystem().getName() - .toString()); + // SRS + String srs; + CoordinateReferenceSystem crs = featureSource.getSchema() + .getCoordinateReferenceSystem(); + try { + Integer epsgCode = CRS.lookupEpsgCode(crs, false); + if (epsgCode != null) + srs = "EPSG:" + epsgCode; + else + srs = crs.toWKT(); + } catch (FactoryException e) { + log.warn("Cannot lookup EPSG code", e); + srs = crs.toWKT(); + } + featureNode.setProperty(GIS_SRS, srs); + + Polygon bboxPolygon; + Geometry envelope = geometry.getEnvelope(); + if (envelope instanceof Point) { + Point pt = (Point) envelope; + Coordinate[] coords = new Coordinate[4]; + for (int i = 0; i < coords.length; i++) + coords[i] = pt.getCoordinate(); + bboxPolygon = JtsJcrUtils.getGeometryFactory() + .createPolygon( + JtsJcrUtils.getGeometryFactory() + .createLinearRing(coords), null); + } else if (envelope instanceof Polygon) { + bboxPolygon = (Polygon) envelope; + } else { + throw new ArgeoException("Unsupported envelope format " + + envelope.getClass()); + } bbox = JtsJcrUtils.writeWkb(featureNode.getSession(), - geometry.getEnvelope()); - featureNode.setProperty(GisNames.GIS_BBOX, bbox); + bboxPolygon); + featureNode.setProperty(GIS_BBOX, bbox); centroid = JtsJcrUtils.writeWkb(featureNode.getSession(), geometry.getCentroid()); - featureNode.setProperty(GisNames.GIS_CENTROID, centroid); + featureNode.setProperty(GIS_CENTROID, centroid); featureSourceNode.getSession().save(); return featureNode; } else { @@ -126,25 +170,21 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { } } - protected Node getNode(Session session, String dataStoreAlias) { + protected Node getDataStoreNode(Session session, String dataStoreAlias) { try { - Node dataStores; - if (!session.itemExists(dataStoresBasePath)) { - dataStores = JcrUtils.mkdirs(session, dataStoresBasePath); - dataStores.getSession().save(); - } else - dataStores = session.getNode(dataStoresBasePath); - - Node dataStoreNode; - if (dataStores.hasNode(dataStoreAlias)) - dataStoreNode = dataStores.getNode(dataStoreAlias); - else { - dataStoreNode = dataStores.addNode(dataStoreAlias, - GisTypes.GIS_DATA_STORE); - dataStoreNode.getSession().save(); - } + // normalize by starting with a '/' + String path = dataStoreAlias.startsWith("/") ? GisJcrConstants.DATA_STORES_BASE_PATH + + dataStoreAlias + : GisJcrConstants.DATA_STORES_BASE_PATH + '/' + + dataStoreAlias; + Node dataStoreNode = JcrUtils.mkdirs(session, path, + GisTypes.GIS_DATA_STORE); + dataStoreNode.setProperty(GIS_ALIAS, dataStoreAlias); + if (session.hasPendingChanges()) + session.save(); return dataStoreNode; } catch (RepositoryException e) { + JcrUtils.discardQuietly(session); throw new ArgeoException("Cannot get node for data store " + dataStoreAlias, e); } @@ -153,12 +193,14 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { public Node getFeatureSourceNode(Session session, String dataStoreAlias, FeatureSource featureSource) { try { - String name = featureSource.getName().toString(); - Node dataStoreNode = getNode(session, dataStoreAlias); - if (dataStoreNode.hasNode(name)) - return dataStoreNode.getNode(name); + // String name = featureSource.getName().toString(); + Name name = featureSource.getName(); + String nodeName = name.getLocalPart(); + Node dataStoreNode = getDataStoreNode(session, dataStoreAlias); + if (dataStoreNode.hasNode(nodeName)) + return dataStoreNode.getNode(nodeName); else { - Node featureSourceNode = dataStoreNode.addNode(name); + Node featureSourceNode = dataStoreNode.addNode(nodeName); featureSourceNode.addMixin(GisTypes.GIS_FEATURE_SOURCE); featureSourceNode.getSession().save(); return featureSourceNode; @@ -176,11 +218,14 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { try { Node dataStoreNode = node.getParent(); // TODO: check a dataStore type - if (!registeredDataStores.containsKey(dataStoreNode.getName())) + if (!dataStoreNode.hasProperty(GIS_ALIAS)) + throw new ArgeoException("Data store " + dataStoreNode + + " is not active."); + String alias = dataStoreNode.getProperty(GIS_ALIAS).getString(); + if (!registeredDataStores.containsKey(alias)) throw new ArgeoException("No data store registered under " + dataStoreNode); - DataStore dataStore = registeredDataStores.get(dataStoreNode - .getName()); + DataStore dataStore = registeredDataStores.get(alias); return dataStore.getFeatureSource(node.getName()); } catch (Exception e) { throw new ArgeoException("Cannot find feature source " + node, e); @@ -192,30 +237,67 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { return null; } - public void register(DataStore dataStore, Map properties) { + public synchronized void register(DataStore dataStore, + Map properties) { if (!properties.containsKey(GeoToolsConstants.ALIAS_KEY)) { log.warn("Cannot register data store " + dataStore + " since it has no '" + GeoToolsConstants.ALIAS_KEY + "' property"); return; } - registeredDataStores.put(properties.get(GeoToolsConstants.ALIAS_KEY), - dataStore); + String alias = properties.get(GeoToolsConstants.ALIAS_KEY); + Node dataStoreNode = getDataStoreNode(systemSession, alias); + try { + dataStoreNode.setProperty(GIS_ALIAS, alias); + + // TODO synchronize namespace if registered + for (Name name : dataStore.getNames()) { + String sourceName = name.getLocalPart(); + if (!dataStoreNode.hasNode(sourceName)) { + Node featureSourceNode = dataStoreNode.addNode(sourceName); + featureSourceNode.addMixin(GisTypes.GIS_FEATURE_SOURCE); + } + } + + // TODO check feature sources which are registered but not available + // anymore + systemSession.save(); + registeredDataStores.put(alias, dataStore); + JcrUtils.discardQuietly(systemSession); + } catch (Exception e) { + throw new ArgeoException("Cannot register data store " + alias + + ", " + dataStore, e); + } } - public void unregister(DataStore dataStore, Map properties) { + public synchronized void unregister(DataStore dataStore, + Map properties) { if (!properties.containsKey(GeoToolsConstants.ALIAS_KEY)) { log.warn("Cannot unregister data store " + dataStore + " since it has no '" + GeoToolsConstants.ALIAS_KEY + "' property"); return; } - registeredDataStores - .remove(properties.get(GeoToolsConstants.ALIAS_KEY)); + + if (!systemSession.isLive()) + return; + + String alias = properties.get(GeoToolsConstants.ALIAS_KEY); + registeredDataStores.remove(alias); + Node dataStoreNode = getDataStoreNode(systemSession, alias); + try { + dataStoreNode.getProperty(GIS_ALIAS).remove(); + systemSession.save(); + } catch (RepositoryException e) { + JcrUtils.discardQuietly(systemSession); + throw new ArgeoException("Cannot unregister data store " + alias + + ", " + dataStore, e); + } } - // public void setSession(Session session) { - // this.session = session; - // } + /** Expects to own this session (will be logged out on dispose) */ + public void setSystemSession(Session systemSession) { + this.systemSession = systemSession; + } }