]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java
Move Commons GIS to Connect
[lgpl/argeo-commons.git] / gis / runtime / org.argeo.gis.geotools / src / main / java / org / argeo / geotools / jcr / GeoJcrIndex.java
diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrIndex.java
deleted file mode 100644 (file)
index b9281b8..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-package org.argeo.geotools.jcr;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventIterator;
-import javax.jcr.observation.EventListener;
-import javax.jcr.observation.ObservationManager;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.geotools.GeoToolsUtils;
-import org.argeo.jcr.JcrUtils;
-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.DefaultTransaction;
-import org.geotools.data.FeatureStore;
-import org.geotools.data.Transaction;
-import org.geotools.feature.FeatureCollection;
-import org.geotools.feature.FeatureCollections;
-import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
-import org.geotools.filter.FilterFactoryImpl;
-import org.geotools.referencing.CRS;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.filter.FilterFactory2;
-import org.opengis.filter.identity.FeatureId;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.NoSuchAuthorityCodeException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.Point;
-import com.vividsolutions.jts.geom.Polygon;
-
-/** Index JCR nodes containing or referencing GIS data. */
-public class GeoJcrIndex implements EventListener, GisNames, GisTypes {
-       // PostGIS convention
-       final static String DEFAULT_GEOM_NAME = "the_geom";
-
-       private final static Log log = LogFactory.getLog(GeoJcrIndex.class);
-
-       private DataStore dataStore;
-       private Session session;
-       private Executor systemExecutionService;
-
-       private String crs = "EPSG:4326";
-
-       /** The key is the workspace */
-       private Map<String, FeatureStore<SimpleFeatureType, SimpleFeature>> geoJcrIndexes = Collections
-                       .synchronizedMap(new HashMap<String, FeatureStore<SimpleFeatureType, SimpleFeature>>());
-
-       // TODO: use common factory finder?
-       private FilterFactory2 ff = new FilterFactoryImpl();
-
-       /** Expects to execute with system authentication */
-       public void init() {
-               if (systemExecutionService != null)// legacy
-                       systemExecutionService.execute(new Runnable() {
-                               public void run() {
-                                       initGeoJcrIndex();
-                               }
-                       });
-               else
-                       initGeoJcrIndex();
-       }
-
-       protected void initGeoJcrIndex() {
-               try {
-                       // create GIS schema
-                       SimpleFeatureType indexType = getWorkspaceGeoJcrIndexType(session
-                                       .getWorkspace().getName());
-                       GeoToolsUtils.createSchemaIfNeeded(dataStore, indexType);
-
-                       // register JCR listeners
-                       ObservationManager om = session.getWorkspace()
-                                       .getObservationManager();
-                       om.addEventListener(this, Event.NODE_ADDED | Event.NODE_REMOVED,
-                                       "/", true, null, null, false);
-
-                       // FIXME: use a different listener for properties since it resets
-                       // the filter
-                       // om.addEventListener(this, Event.PROPERTY_CHANGED, "/",
-                       // true, null, new String[] { GIS_LOCATED }, false);
-
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot initialize GeoJcr index", e);
-               }
-       }
-
-       public void dispose() {
-       }
-
-       public void onEvent(final EventIterator events) {
-               final FeatureCollection<SimpleFeatureType, SimpleFeature> toAdd = FeatureCollections
-                               .newCollection();
-               final Set<FeatureId> toRemove = new HashSet<FeatureId>();
-
-               // execute with system authentication so that JCR can be read
-               systemExecutionService.execute(new Runnable() {
-                       public void run() {
-                               while (events.hasNext()) {
-                                       Event event = events.nextEvent();
-                                       try {
-                                               Integer eventType = event.getType();
-                                               if (Event.NODE_ADDED == eventType) {
-                                                       Node node = session.getNodeByIdentifier(event
-                                                                       .getIdentifier());
-                                                       if (node.isNodeType(GIS_INDEXED)) {
-                                                               SimpleFeature feature = mapNodeToFeature(node,
-                                                                               getGeoJcrIndex().getSchema());
-                                                               toAdd.add(feature);
-                                                       }
-                                               } else if (Event.NODE_REMOVED == eventType) {
-                                                       // we have no way to check whether the node was
-                                                       // actually
-                                                       // geoindexed without querying the index, this is
-                                                       // therefore
-                                                       // more optimal to create a filter with all ideas
-                                                       // and apply
-                                                       // a remove later on
-                                                       String id = event.getIdentifier();
-                                                       toRemove.add(ff.featureId(id));
-                                               } else if (Event.PROPERTY_CHANGED == eventType) {
-                                                       // TODO: monitor changes to SRS, BBOX AND CENTROID
-                                               }
-                                       } catch (Exception e) {
-                                               log.error("Cannot process event " + event, e);
-                                       }
-                               }
-                       }
-               });
-
-               // TODO: this may be more optimal to persist in one single
-               // transaction,
-               // but we will loose modifications on all nodes if a single one
-               // fails
-               try {
-                       Transaction transaction = new DefaultTransaction();
-                       getGeoJcrIndex().setTransaction(transaction);
-                       try {
-                               // points
-                               getGeoJcrIndex().addFeatures(toAdd);
-                               if (toRemove.size() != 0)
-                                       getGeoJcrIndex().removeFeatures(ff.id(toRemove));
-                               transaction.commit();
-                       } catch (Exception e) {
-                               transaction.rollback();
-                               throw new ArgeoException("Cannot persist changes", e);
-                       } finally {
-                               transaction.close();
-                       }
-               } catch (ArgeoException e) {
-                       throw e;
-               } catch (IOException e) {
-                       throw new ArgeoException("Unexpected issue with the transaction", e);
-               }
-       }
-
-       protected FeatureStore<SimpleFeatureType, SimpleFeature> getGeoJcrIndex() {
-               String workspaceName = session.getWorkspace().getName();
-               if (!geoJcrIndexes.containsKey(workspaceName)) {
-                       SimpleFeatureType indexType = getWorkspaceGeoJcrIndexType(workspaceName);
-                       FeatureStore<SimpleFeatureType, SimpleFeature> geoIndex = GeoToolsUtils
-                                       .getFeatureStore(dataStore, indexType.getName());
-                       geoJcrIndexes.put(workspaceName, geoIndex);
-               }
-               return geoJcrIndexes.get(workspaceName);
-       }
-
-       protected SimpleFeatureType getWorkspaceGeoJcrIndexType(String workspaceName) {
-
-               SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
-               builder.setNamespaceURI(GIS_NAMESPACE);
-               builder.setName(workspaceName + "_geojcr_index");
-               try {
-                       builder.setCRS(CRS.decode(crs));
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot set CRS " + crs, e);
-               }
-
-               builder.setDefaultGeometry(JcrUtils.normalize(GIS_BBOX));
-               builder.add(JcrUtils.normalize(GIS_BBOX), Polygon.class);
-               builder.add(JcrUtils.normalize(GIS_CENTROID), Point.class);
-
-               builder.add(JcrUtils.normalize("jcr:uuid"), String.class);
-               builder.add(JcrUtils.normalize("jcr:path"), String.class);
-               builder.add(JcrUtils.normalize("jcr:primaryType"), String.class);
-               // mix:lastModified
-               builder.add(JcrUtils.normalize("jcr:lastModified"), Date.class);
-               builder.add(JcrUtils.normalize("jcr:lastModifiedBy"), String.class);
-
-               return builder.buildFeatureType();
-       }
-
-       protected SimpleFeature mapNodeToFeature(Node node, SimpleFeatureType type) {
-               try {
-                       SimpleFeatureBuilder builder = new SimpleFeatureBuilder(type);
-
-                       Node locatedNode;
-                       if (node.isNodeType(GIS_LOCATED)) {
-                               locatedNode = node;
-                       } else if (node.isNodeType(GIS_INDEXED)) {
-                               locatedNode = findLocatedParent(node);
-                       } else {
-                               throw new ArgeoException("Unsupported node " + node);
-                       }
-
-                       // TODO: reproject to the feature store SRS
-                       Polygon bbox = (Polygon) JtsJcrUtils.readWkb(locatedNode
-                                       .getProperty(GIS_BBOX));
-                       builder.set(JcrUtils.normalize(GIS_BBOX), bbox);
-                       Point centroid = (Point) JtsJcrUtils.readWkb(locatedNode
-                                       .getProperty(GIS_CENTROID));
-                       builder.set(JcrUtils.normalize(GIS_CENTROID), centroid);
-
-                       builder.set(JcrUtils.normalize("jcr:uuid"), node.getIdentifier());
-                       builder.set(JcrUtils.normalize("jcr:path"), node.getPath());
-                       builder.set(JcrUtils.normalize("jcr:primaryType"), node
-                                       .getPrimaryNodeType().getName());
-                       if (node.hasProperty(Property.JCR_LAST_MODIFIED))
-                               builder.set(JcrUtils.normalize("jcr:lastModified"), node
-                                               .getProperty(Property.JCR_LAST_MODIFIED).getDate()
-                                               .getTime());
-                       if (node.hasProperty(Property.JCR_LAST_MODIFIED_BY))
-                               builder.set(JcrUtils.normalize("jcr:lastModifiedBy"), node
-                                               .getProperty(Property.JCR_LAST_MODIFIED_BY).getString());
-                       return builder.buildFeature(node.getIdentifier());
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot map " + node + " to " + type, e);
-               }
-       }
-
-       protected Node findLocatedParent(Node child) {
-               try {
-                       if (child.getParent().isNodeType(GIS_LOCATED))
-                               return child.getParent();
-                       else
-                               return findLocatedParent(child.getParent());
-               } catch (Exception e) {
-                       // also if child is root node
-                       throw new ArgeoException("Cannot find located parent", e);
-               }
-       }
-
-       /** Returns the node as a point in the CRS of the related feature store. */
-       protected Geometry reproject(CoordinateReferenceSystem crs,
-                       Geometry geometry, CoordinateReferenceSystem targetCrs) {
-               // transform if not same CRS
-               // FIXME: there is certainly a more standard way to reproject
-               if (!targetCrs.getIdentifiers().contains(crs.getName())) {
-                       throw new ArgeoException("Reprojection not yet supported");
-                       // MathTransform transform;
-                       // try {
-                       // transform = CRS.findMathTransform(nodeCrs, featureStoreCrs);
-                       // if (geometry instanceof Point) {
-                       // Point point = (Point) geometry;
-                       // DirectPosition2D pos = new DirectPosition2D(nodeCrs,
-                       // point.getX(), point.getY());
-                       // DirectPosition targetPos = transform.transform(pos, null);
-                       // return geometryFactory.createPoint(new Coordinate(targetPos
-                       // .getCoordinate()[0], targetPos.getCoordinate()[1]));
-                       // } else if (geometry instanceof Polygon) {
-                       // Polygon polygon = (Polygon) geometry;
-                       // List<Coordinate> coordinates = new ArrayList<Coordinate>();
-                       // for (Coordinate coo : polygon.getExteriorRing()) {
-                       // DirectPosition pos = new DirectPosition2D(nodeCrs,
-                       // coo.x, coo.y);
-                       // DirectPosition targetPos = transform.transform(pos,
-                       // null);
-                       // // coordinates.add(o)
-                       // }
-                       // LinearRing ring = geometryFactory
-                       // .createLinearRing(coordinates
-                       // .toArray(new Coordinate[coordinates.size()]));
-                       // return geometryFactory.createPolygon(ring, null);
-                       // }
-                       // } catch (Exception e) {
-                       // throw new ArgeoException("Cannot transform from " + nodeCrs
-                       // + " to " + featureStoreCrs, e);
-                       // }
-               } else {
-                       return geometry;
-               }
-       }
-
-       public void setDataStore(DataStore dataStore) {
-               this.dataStore = dataStore;
-       }
-
-       public void setSession(Session session) {
-               this.session = session;
-       }
-
-       public void setSystemExecutionService(Executor systemExecutionService) {
-               this.systemExecutionService = systemExecutionService;
-       }
-
-}