]> git.argeo.org Git - lgpl/argeo-commons.git/blob - gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java
Improve Jackrabbit security
[lgpl/argeo-commons.git] / gis / runtime / org.argeo.gis.geotools / src / main / java / org / argeo / geotools / jcr / SimpleGeoJcrMapper.java
1 package org.argeo.geotools.jcr;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.TreeMap;
9
10 import javax.jcr.Binary;
11 import javax.jcr.Node;
12 import javax.jcr.RepositoryException;
13 import javax.jcr.Session;
14
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.argeo.ArgeoException;
18 import org.argeo.geotools.GeoToolsConstants;
19 import org.argeo.geotools.GeoToolsUtils;
20 import org.argeo.jcr.JcrUtils;
21 import org.argeo.jcr.gis.GisNames;
22 import org.argeo.jcr.gis.GisTypes;
23 import org.argeo.jts.jcr.JtsJcrUtils;
24 import org.geotools.data.DataStore;
25 import org.geotools.data.FeatureSource;
26 import org.geotools.referencing.CRS;
27 import org.opengis.feature.simple.SimpleFeature;
28 import org.opengis.feature.simple.SimpleFeatureType;
29 import org.opengis.feature.type.Name;
30 import org.opengis.referencing.FactoryException;
31 import org.opengis.referencing.crs.CoordinateReferenceSystem;
32
33 import com.vividsolutions.jts.geom.Coordinate;
34 import com.vividsolutions.jts.geom.Geometry;
35 import com.vividsolutions.jts.geom.Point;
36 import com.vividsolutions.jts.geom.Polygon;
37
38 public class SimpleGeoJcrMapper implements GeoJcrMapper {
39 private final static Log log = LogFactory.getLog(SimpleGeoJcrMapper.class);
40
41 private String dataStoresBasePath = "/gis/dataStores";
42
43 private Map<String, DataStore> registeredDataStores = Collections
44 .synchronizedSortedMap(new TreeMap<String, DataStore>());
45
46 public Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> getPossibleFeatureSources() {
47 Map<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>> res = new TreeMap<String, List<FeatureSource<SimpleFeatureType, SimpleFeature>>>();
48 dataStores: for (String alias : registeredDataStores.keySet()) {
49 DataStore dataStore = registeredDataStores.get(alias);
50 List<Name> names;
51 try {
52 names = dataStore.getNames();
53 } catch (IOException e) {
54 log.warn("Cannot list features sources of data store " + alias,
55 e);
56 continue dataStores;
57 }
58 List<FeatureSource<SimpleFeatureType, SimpleFeature>> lst = new ArrayList<FeatureSource<SimpleFeatureType, SimpleFeature>>();
59 for (Name name : names) {
60 try {
61 lst.add(dataStore.getFeatureSource(name));
62 } catch (IOException e) {
63 if (log.isTraceEnabled())
64 log.trace("Skipping " + name + " of data store "
65 + alias + " because it is probably"
66 + " not a feature source", e);
67 }
68 }
69 res.put(alias, lst);
70 }
71 return res;
72 }
73
74 // public Node getNode(String dataStoreAlias,
75 // FeatureSource<SimpleFeatureType, SimpleFeature> featureSource,
76 // SimpleFeature feature) {
77 // StringBuffer pathBuf = new StringBuffer(dataStoresBasePath);
78 // pathBuf.append('/').append(dataStoreAlias);
79 // pathBuf.append('/').append(featureSource.getName());
80 //
81 // // TODO: use centroid or bbox to create some depth
82 // // Geometry geometry = (Geometry)feature.getDefaultGeometry();
83 // // Point centroid = geometry.getCentroid();
84 //
85 // pathBuf.append('/').append(feature.getID());
86 //
87 // String path = pathBuf.toString();
88 // try {
89 // if (session.itemExists(path))
90 // return session.getNode(path);
91 // else
92 // return JcrUtils.mkdirs(session, path);
93 // } catch (RepositoryException e) {
94 // throw new ArgeoException("Cannot get feature node for " + path, e);
95 // }
96 // }
97
98 public Node getFeatureNode(Node featureSourceNode, String featureId) {
99 Binary bbox = null;
100 Binary centroid = null;
101 try {
102 if (!featureSourceNode.hasNode(featureId)) {
103 FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = getFeatureSource(featureSourceNode);
104 SimpleFeature feature = GeoToolsUtils.querySingleFeature(
105 featureSource, featureId);
106 Node featureNode = featureSourceNode.addNode(featureId);
107 featureNode.addMixin(GisTypes.GIS_FEATURE);
108 Geometry geometry = (Geometry) feature.getDefaultGeometry();
109
110 // SRS
111 String srs;
112 CoordinateReferenceSystem crs = featureSource.getSchema()
113 .getCoordinateReferenceSystem();
114 try {
115 Integer epsgCode = CRS.lookupEpsgCode(crs, false);
116 if (epsgCode != null)
117 srs = "EPSG:" + epsgCode;
118 else
119 srs = crs.toWKT();
120 } catch (FactoryException e) {
121 log.warn("Cannot lookup EPSG code", e);
122 srs = crs.toWKT();
123 }
124 featureNode.setProperty(GisNames.GIS_SRS, srs);
125
126 Polygon bboxPolygon;
127 Geometry envelope = geometry.getEnvelope();
128 if (envelope instanceof Point) {
129 Point pt = (Point) envelope;
130 Coordinate[] coords = new Coordinate[4];
131 for (int i = 0; i < coords.length; i++)
132 coords[i] = pt.getCoordinate();
133 bboxPolygon = JtsJcrUtils.getGeometryFactory()
134 .createPolygon(
135 JtsJcrUtils.getGeometryFactory()
136 .createLinearRing(coords), null);
137 } else if (envelope instanceof Polygon) {
138 bboxPolygon = (Polygon) envelope;
139 } else {
140 throw new ArgeoException("Unsupported envelope format "
141 + envelope.getClass());
142 }
143 bbox = JtsJcrUtils.writeWkb(featureNode.getSession(),
144 bboxPolygon);
145 featureNode.setProperty(GisNames.GIS_BBOX, bbox);
146 centroid = JtsJcrUtils.writeWkb(featureNode.getSession(),
147 geometry.getCentroid());
148 featureNode.setProperty(GisNames.GIS_CENTROID, centroid);
149 featureSourceNode.getSession().save();
150 return featureNode;
151 } else {
152 return featureSourceNode.getNode(featureId);
153 }
154 } catch (RepositoryException e) {
155 throw new ArgeoException("Cannot get feature node for feature "
156 + featureId + " from " + featureSourceNode, e);
157 } finally {
158 JcrUtils.closeQuietly(bbox);
159 JcrUtils.closeQuietly(centroid);
160 }
161 }
162
163 protected Node getNode(Session session, String dataStoreAlias) {
164 try {
165 Node dataStores;
166 if (!session.itemExists(dataStoresBasePath)) {
167 dataStores = JcrUtils.mkdirs(session, dataStoresBasePath);
168 dataStores.getSession().save();
169 } else
170 dataStores = session.getNode(dataStoresBasePath);
171
172 Node dataStoreNode;
173 if (dataStores.hasNode(dataStoreAlias))
174 dataStoreNode = dataStores.getNode(dataStoreAlias);
175 else {
176 dataStoreNode = dataStores.addNode(dataStoreAlias,
177 GisTypes.GIS_DATA_STORE);
178 dataStoreNode.getSession().save();
179 }
180 return dataStoreNode;
181 } catch (RepositoryException e) {
182 throw new ArgeoException("Cannot get node for data store "
183 + dataStoreAlias, e);
184 }
185 }
186
187 public Node getFeatureSourceNode(Session session, String dataStoreAlias,
188 FeatureSource<SimpleFeatureType, SimpleFeature> featureSource) {
189 try {
190 String name = featureSource.getName().toString();
191 Node dataStoreNode = getNode(session, dataStoreAlias);
192 if (dataStoreNode.hasNode(name))
193 return dataStoreNode.getNode(name);
194 else {
195 Node featureSourceNode = dataStoreNode.addNode(name);
196 featureSourceNode.addMixin(GisTypes.GIS_FEATURE_SOURCE);
197 featureSourceNode.getSession().save();
198 return featureSourceNode;
199 }
200 } catch (RepositoryException e) {
201 throw new ArgeoException(
202 "Cannot get feature source node for data store "
203 + dataStoreAlias + " and feature source "
204 + featureSource.getName(), e);
205 }
206 }
207
208 public FeatureSource<SimpleFeatureType, SimpleFeature> getFeatureSource(
209 Node node) {
210 try {
211 Node dataStoreNode = node.getParent();
212 // TODO: check a dataStore type
213 if (!registeredDataStores.containsKey(dataStoreNode.getName()))
214 throw new ArgeoException("No data store registered under "
215 + dataStoreNode);
216 DataStore dataStore = registeredDataStores.get(dataStoreNode
217 .getName());
218 return dataStore.getFeatureSource(node.getName());
219 } catch (Exception e) {
220 throw new ArgeoException("Cannot find feature source " + node, e);
221 }
222 }
223
224 public SimpleFeature getFeature(Node node) {
225 // TODO Auto-generated method stub
226 return null;
227 }
228
229 public void register(DataStore dataStore, Map<String, String> properties) {
230 if (!properties.containsKey(GeoToolsConstants.ALIAS_KEY)) {
231 log.warn("Cannot register data store " + dataStore
232 + " since it has no '" + GeoToolsConstants.ALIAS_KEY
233 + "' property");
234 return;
235 }
236 registeredDataStores.put(properties.get(GeoToolsConstants.ALIAS_KEY),
237 dataStore);
238 }
239
240 public void unregister(DataStore dataStore, Map<String, String> properties) {
241 if (!properties.containsKey(GeoToolsConstants.ALIAS_KEY)) {
242 log.warn("Cannot unregister data store " + dataStore
243 + " since it has no '" + GeoToolsConstants.ALIAS_KEY
244 + "' property");
245 return;
246 }
247 registeredDataStores
248 .remove(properties.get(GeoToolsConstants.ALIAS_KEY));
249 }
250 }