From: Mathieu Baudier Date: Thu, 10 Mar 2011 13:32:43 +0000 (+0000) Subject: Improve GIS X-Git-Tag: argeo-commons-2.1.30~1377 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=7fe4a16dad045373bb014724733c1bbb175d44b5;p=lgpl%2Fargeo-commons.git Improve GIS git-svn-id: https://svn.argeo.org/commons/trunk@4278 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/EditNode.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/EditNode.java new file mode 100644 index 000000000..8d0e87dea --- /dev/null +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/EditNode.java @@ -0,0 +1,54 @@ +package org.argeo.eclipse.ui.jcr.commands; + +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.Property; +import javax.jcr.nodetype.NodeType; + +import org.argeo.eclipse.ui.dialogs.Error; +import org.argeo.eclipse.ui.jcr.editors.NodeEditorInput; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** Generic command to open a path in an editor. */ +public class EditNode extends AbstractHandler { + public final static String EDITOR_PARAM = "editor"; + + private String defaultEditorId; + + private Map nodeTypeToEditor = new HashMap(); + + public Object execute(ExecutionEvent event) throws ExecutionException { + String path = event.getParameter(Property.JCR_PATH); + + String type = event.getParameter(NodeType.NT_NODE_TYPE); + if (type == null) + type = NodeType.NT_UNSTRUCTURED; + + String editorId = event.getParameter(NodeType.NT_NODE_TYPE); + if (editorId == null) + editorId = nodeTypeToEditor.containsKey(type) ? nodeTypeToEditor + .get(type) : defaultEditorId; + + NodeEditorInput nei = new NodeEditorInput(path); + + try { + HandlerUtil.getActiveWorkbenchWindow(event).getActivePage() + .openEditor(nei, editorId); + } catch (PartInitException e) { + Error.show("Cannot open " + editorId + " with " + path + + " of type " + type, e); + } + // TODO Auto-generated method stub + return null; + } + + public void setDefaultEditorId(String defaultEditorId) { + this.defaultEditorId = defaultEditorId; + } + +} diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/NodeEditorInput.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/NodeEditorInput.java new file mode 100644 index 000000000..18718388b --- /dev/null +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/NodeEditorInput.java @@ -0,0 +1,42 @@ +package org.argeo.eclipse.ui.jcr.editors; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +public class NodeEditorInput implements IEditorInput { + private final String path; + + public NodeEditorInput(String path) { + this.path = path; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return path; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return path; + } + + public String getPath() { + return path; + } + +} diff --git a/eclipse/runtime/org.argeo.eclipse.ui.rcp/src/main/java/org/argeo/eclipse/ui/specific/FileHandler.java b/eclipse/runtime/org.argeo.eclipse.ui.rcp/src/main/java/org/argeo/eclipse/ui/specific/FileHandler.java index b9c4d31d3..e9d7d23d4 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui.rcp/src/main/java/org/argeo/eclipse/ui/specific/FileHandler.java +++ b/eclipse/runtime/org.argeo.eclipse.ui.rcp/src/main/java/org/argeo/eclipse/ui/specific/FileHandler.java @@ -51,8 +51,10 @@ public class FileHandler { Desktop desktop = null; if (Desktop.isDesktopSupported()) { desktop = Desktop.getDesktop(); + desktop.open(file); + } else { + throw new ArgeoException("Desktop integration not supported."); } - desktop.open(file); } catch (IOException e) { throw new ArgeoException("Cannot open file " + file.getName(), e); } diff --git a/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/dialogs/Error.java b/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/dialogs/Error.java index 4a0f4fa0d..4e6716ecc 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/dialogs/Error.java +++ b/eclipse/runtime/org.argeo.eclipse.ui/src/main/java/org/argeo/eclipse/ui/dialogs/Error.java @@ -17,6 +17,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +/** !Generic error dialog to be used in try/catch blocks*/ public class Error extends TitleAreaDialog { private final static Log log = LogFactory.getLog(Error.class); diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF b/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF index bc9ca2689..005d8c668 100644 --- a/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/MANIFEST.MF @@ -11,9 +11,11 @@ Require-Bundle: org.eclipse.rap.ui, Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy Import-Package: com.vividsolutions.jts.geom;version="1.10.0", + javax.jcr;version="2.0.0", org.apache.commons.logging;version="1.1.1", org.argeo.eclipse.spring, org.argeo.geotools, + org.argeo.geotools.jcr, org.argeo.gis.ui, org.argeo.gis.ui.editors, org.geotools.data, diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/spring/openlayers.xml b/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/spring/openlayers.xml index 73460c672..b2ec854fb 100644 --- a/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/spring/openlayers.xml +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/spring/openlayers.xml @@ -6,6 +6,6 @@ http://www.springframework.org/schema/beans/spring-beans.xsd"> + class="org.argeo.gis.ui.rap.openlayers.OpenLayersMapControlCreator"> diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/spring/osgi.xml b/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/spring/osgi.xml index 9d030d8f8..7a4ec53ed 100644 --- a/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/spring/osgi.xml +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/META-INF/spring/osgi.xml @@ -6,6 +6,8 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> + + \ No newline at end of file diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/MapContextAdapter.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/MapContextAdapter.java deleted file mode 100644 index 8adf05799..000000000 --- a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/MapContextAdapter.java +++ /dev/null @@ -1,310 +0,0 @@ -package org.argeo.gis.ui.rap.openlayers; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.geotools.GeoToolsUtils; -import org.argeo.gis.ui.rap.openlayers.custom.JSON; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.geotools.data.FeatureSource; -import org.geotools.feature.FeatureCollection; -import org.geotools.feature.FeatureIterator; -import org.geotools.map.MapContext; -import org.geotools.map.event.MapLayerListEvent; -import org.geotools.map.event.MapLayerListListener; -import org.opengis.feature.simple.SimpleFeature; -import org.opengis.feature.simple.SimpleFeatureType; -import org.opengis.filter.Filter; -import org.opengis.filter.identity.FeatureId; -import org.polymap.openlayers.rap.widget.base.OpenLayersEventListener; -import org.polymap.openlayers.rap.widget.base.OpenLayersObject; -import org.polymap.openlayers.rap.widget.base_types.Bounds; -import org.polymap.openlayers.rap.widget.base_types.OpenLayersMap; -import org.polymap.openlayers.rap.widget.controls.EditingToolbarControl; -import org.polymap.openlayers.rap.widget.controls.SelectFeatureControl; -import org.polymap.openlayers.rap.widget.controls.SnappingControl; -import org.polymap.openlayers.rap.widget.features.VectorFeature; -import org.polymap.openlayers.rap.widget.geometry.LineStringGeometry; -import org.polymap.openlayers.rap.widget.geometry.PointGeometry; -import org.polymap.openlayers.rap.widget.layers.VectorLayer; - -import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.MultiPolygon; -import com.vividsolutions.jts.geom.Point; - -public class MapContextAdapter implements MapLayerListListener, - OpenLayersEventListener, MouseListener { - private final static Log log = LogFactory.getLog(MapContextAdapter.class); - - private final MapContext mapContext; - private final OpenLayersMap map; - - // edit - private VectorLayer edit_layer; - private EditingToolbarControl edit_toolbar; - private VectorLayer selectable_boxes_layer; - - private Map vectorLayers = Collections - .synchronizedMap(new HashMap()); - private Map> featureSources = Collections - .synchronizedMap(new HashMap>()); - - public MapContextAdapter(MapContext mapContext, OpenLayersMap openLayersMap) { - this.mapContext = mapContext; - this.map = openLayersMap; - - mapContext.addMapLayerListListener(this); - - HashMap payloadMap = new HashMap(); - payloadMap.put("layername", "event.layer.name"); - this.map.events.register(this, "changebaselayer", payloadMap); - payloadMap.put("property", "event.property"); - payloadMap.put("visibility", "event.layer.visibility"); - this.map.events.register(this, "changelayer", payloadMap); - - // edit - HashMap editPayload = new HashMap(); - editPayload.put("layername", "event.layer.name"); - editPayload.put("x", "event.xy.x"); - editPayload.put("y", "event.xy.y"); - edit_layer = new VectorLayer("edit layer"); - edit_layer.events.register(this, "beforefeatureadded", null); - edit_layer.events.register(this, "afterfeatureadded", editPayload); - this.map.addLayer(edit_layer); - edit_layer.setVisibility(false); - - // add vector layer with some boxes to demonstrate the modify feature - // feature - // selectPayload.put("id", "feature.id"); - // selectPayload.put("lon", "feature.lonlat.lon"); - // selectPayload.put("lat", "feature.lonlat.lon"); - selectable_boxes_layer = new VectorLayer("selectable boxes"); - HashMap selectPayload = new HashMap(); - selectPayload.put("features", selectable_boxes_layer.getJSObjRef() - + ".selectedFeatures[0].id"); - selectPayload.put("id", "event.feature.id"); - selectPayload.put("fid", "event.feature.fid"); - selectPayload.put("geometry", "event.feature.geometry"); - selectPayload.put("bounds", "event.feature.bounds"); - selectPayload.put("lonlat", "event.feature.lonlat"); - selectable_boxes_layer.events.register(this, "featureselected", - selectPayload); - // selectable_boxes_layer.events.register(this, "featureunselected", - // selectPayload); - // selectable_boxes_layer.events.register(this, - // SelectFeatureControl.EVENT_HIGHLIGHTED, selectPayload); - // selectable_boxes_layer.events.register(this, - // SelectFeatureControl.EVENT_SELECTED, null); - // selectable_boxes_layer.events.register(this, "featuremodified", - // null); - map.addLayer(selectable_boxes_layer); - VectorFeature vector_feature = new VectorFeature(new Bounds( - -1952081.800054420018569, 1118889.974857959896326, - 7124447.410769510082901, 5465442.183322750031948).toGeometry()); - selectable_boxes_layer.addFeatures(vector_feature); - selectable_boxes_layer.setVisibility(false); - - SelectFeatureControl mfc = new SelectFeatureControl( - selectable_boxes_layer, 0); - map.addControl(mfc); - // mfc.setHighlightOnly(true); - mfc.setRenderIntent("temporary"); - mfc.activate(); - - HashMap mapPayload = new HashMap(); - mapPayload.put("bbox", map.getJSObjRef() + ".getExtent().toBBOX()"); - mapPayload.put("lonlat", map.getJSObjRef() - + ".getLonLatFromViewPortPx(event.xy)"); - mapPayload.put("x", "event.xy.x"); - mapPayload.put("y", "event.xy.y"); - mapPayload.put("button", "event.button"); - map.events.register(this, "click", mapPayload); - } - - /* - * OPENLAYERS MAP - */ - - public void process_event(OpenLayersObject source, String eventName, - HashMap payload) { - if (log.isDebugEnabled()) - log.debug("openlayers event from " + source); - if (eventName.equals("changebaselayer")) { - if (log.isDebugEnabled()) - log.debug("client changed baselayer to '" - + payload.get("layername") + "' " - + payload.get("property")); - } else if (eventName.equals("changelayer")) { - if (log.isDebugEnabled()) - log.debug("client changed layer '" + payload.get("layername") - + "' " + payload.get("property") + "' " - + payload.get("visibility")); - if (payload.get("property").equals("visibility")) { - Boolean visible = payload.get("visibility").equals("true"); - if (payload.get("layername").equals(edit_layer.getName())) { - if (visible) { - // adding edit control for the vector layer created - // above - edit_toolbar = new EditingToolbarControl(edit_layer); - map.addControl(edit_toolbar); - VectorLayer[] snapping_layers = { edit_layer, - selectable_boxes_layer }; - SnappingControl snap_ctrl = new SnappingControl( - edit_layer, snapping_layers, false); - snap_ctrl.activate(); - map.addControl(snap_ctrl); - - } else { - edit_toolbar.deactivate(); - map.removeControl(edit_toolbar); - } - } - } - } else if (eventName.equals("beforefeatureadded")) { - if (log.isDebugEnabled()) - log.debug("before feature added on layer '" - + payload.get("layername") + "' x=" + payload.get("x") - + "' y=" + payload.get("y")); - } else if (eventName.equals("afterfeatureadded")) { - if (log.isDebugEnabled()) - log.debug("after feature added on layer '" - + payload.get("layername") + "' x=" + payload.get("x") - + "' y=" + payload.get("y")); - } else if (eventName.equals("featureselected")) { - if (log.isDebugEnabled()) - log.debug("feature selected " + payload); - VectorLayer layer = (VectorLayer) source; - log.debug(layer.getJSObjRef()); - - String layerId = payload.get("layerId"); - String featureId = payload.get("featureId"); - FeatureSource featureSource = featureSources - .get(layerId); - SimpleFeature feature = GeoToolsUtils.querySingleFeature( - featureSource, featureId); - log.debug("Geotools Feature id : " + feature.getID()); - } else if (log.isDebugEnabled()) - log.debug("unknown event " + eventName + " : " + payload); - - } - - /* - * MAP CONTEXT - */ - - @SuppressWarnings("unchecked") - public void layerAdded(MapLayerListEvent event) { - if (log.isDebugEnabled()) - log.debug("Map context layer added " + event); - - FeatureIterator featureIterator = null; - try { - FeatureSource featureSource = (FeatureSource) event - .getLayer().getFeatureSource(); - - String layerName = featureSource.getName().toString(); - String layerId = layerName; - VectorLayer vectorLayer = new VectorLayer(layerName); - vectorLayer.setObjAttr("id", layerId); - vectorLayers.put(layerId, vectorLayer); - featureSources.put(layerId, featureSource); - - // selection - HashMap selectPayload = new HashMap(); - selectPayload.put("featureId", "event.feature.id"); - selectPayload.put("geometry", "event.feature.geometry"); - selectPayload.put("layerId", "event.feature.layer.id"); - vectorLayer.events.register(this, "featureselected", selectPayload); - SelectFeatureControl mfc = new SelectFeatureControl(vectorLayer, 0); - map.addControl(mfc); - mfc.setRenderIntent("temporary"); - mfc.activate(); - - FeatureCollection featureCollection = featureSource - .getFeatures(); - featureIterator = featureCollection.features(); - // TODO make this interruptible since it can easily block with huge - // data - while (featureIterator.hasNext()) { - SimpleFeature feature = featureIterator.next(); - Geometry geom = (Geometry) feature.getDefaultGeometry(); - if (log.isDebugEnabled()) - log.debug("Feature " + feature.getID() + ", " - + feature.getClass().getName()); - // log.debug(" Geom: " + geom.getClass() + ", centroid=" - // + geom.getCentroid()); - if (geom instanceof Point) { - Point mp = (Point) geom; - if (log.isDebugEnabled()) - log.debug(" " + mp.getX() + "," + mp.getY()); - PointGeometry pg = new PointGeometry(mp.getX(), mp.getY()); - VectorFeature vf = new VectorFeature(pg); - vf.setObjAttr("id", feature.getID()); - vectorLayer.addFeatures(vf); - } else if (geom instanceof MultiPolygon) { - MultiPolygon mp = (MultiPolygon) geom; - List points = new ArrayList(); - for (Coordinate coo : mp.getCoordinates()) { - // if (log.isDebugEnabled()) - // log.debug(" " + coo.x + "," + coo.y); - points.add(new PointGeometry(coo.x, coo.y)); - } - VectorFeature vf = new VectorFeature( - new LineStringGeometry( - points.toArray(new PointGeometry[points - .size()]))); - vectorLayer.addFeatures(vf); - } - } - map.addLayer(vectorLayer); - } catch (IOException e) { - log.error("Cannot add layer " + event.getLayer(), e); - } finally { - GeoToolsUtils.closeQuietly(featureIterator); - } - } - - public void layerRemoved(MapLayerListEvent event) { - if (log.isDebugEnabled()) - log.debug("Map context layer removed " + event); - } - - public void layerChanged(MapLayerListEvent event) { - if (log.isDebugEnabled()) - log.debug("Map context layer changed " + event); - } - - public void layerMoved(MapLayerListEvent event) { - if (log.isDebugEnabled()) - log.debug("Map context layer moved " + event); - } - - /* - * MOUSE LISTENER - */ - public void mouseDoubleClick(MouseEvent e) { - if (log.isDebugEnabled()) - log.debug("Mouse double click " + e); - } - - public void mouseDown(MouseEvent e) { - if (log.isDebugEnabled()) - log.debug("Mouse down " + e); - } - - public void mouseUp(MouseEvent e) { - if (log.isDebugEnabled()) - log.debug("Mouse up " + e); - } - -} diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java index c38a7f5b9..92a19fbe0 100644 --- a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapControlCreator.java @@ -1,67 +1,22 @@ package org.argeo.gis.ui.rap.openlayers; -import org.argeo.gis.ui.MapContextProvider; +import javax.jcr.Node; + +import org.argeo.geotools.jcr.GeoJcrMapper; import org.argeo.gis.ui.MapControlCreator; -import org.argeo.gis.ui.rap.openlayers.custom.BingLayer; -import org.argeo.gis.ui.rap.openlayers.custom.GoogleLayer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; +import org.argeo.gis.ui.MapViewer; import org.eclipse.swt.widgets.Composite; -import org.polymap.openlayers.rap.widget.OpenLayersWidget; -import org.polymap.openlayers.rap.widget.base_types.OpenLayersMap; -import org.polymap.openlayers.rap.widget.base_types.Projection; -import org.polymap.openlayers.rap.widget.controls.KeyboardDefaultsControl; -import org.polymap.openlayers.rap.widget.controls.LayerSwitcherControl; -import org.polymap.openlayers.rap.widget.controls.MouseDefaultsControl; -import org.polymap.openlayers.rap.widget.controls.NavigationControl; -import org.polymap.openlayers.rap.widget.controls.OverviewMapControl; -import org.polymap.openlayers.rap.widget.controls.PanZoomBarControl; -import org.polymap.openlayers.rap.widget.controls.ScaleControl; -import org.polymap.openlayers.rap.widget.layers.OSMLayer; -import org.polymap.openlayers.rap.widget.layers.WMSLayer; public class OpenLayersMapControlCreator implements MapControlCreator { - public Composite createMapControl(Composite parent, - MapContextProvider mapContextProvider) { - - // OpenLayersWidget openLayersWidget = new OpenLayersWidget(parent, - // SWT.MULTI | SWT.WRAP, "/js_lib/OpenLayers/OpenLayers.js"); - OpenLayersWidget openLayersWidget = new OpenLayersWidget(parent, - SWT.MULTI | SWT.WRAP); - openLayersWidget.setLayoutData(new GridData(GridData.FILL_BOTH)); - - OpenLayersMap map = openLayersWidget.getMap(); - map.setProjection(new Projection("EPSG:900913")); - map.setDisplayProjection(new Projection("EPSG:4326")); - map.setUnits("m"); - - map.addControl(new LayerSwitcherControl()); - NavigationControl navigationControl = new NavigationControl(); - navigationControl.setObjAttr("handleRightClicks", true); - navigationControl.setObjAttr("zoomBoxEnabled", true); - map.addControl(navigationControl); - map.addControl(new KeyboardDefaultsControl()); - map.addControl(new PanZoomBarControl()); - map.addControl(new ScaleControl()); - - // WMSLayer baseLayer = new WMSLayer("argeo_dev", - // "https://dev.argeo.org/geoserver/wms?", - // "naturalearth:10m_admin_0_countries"); - - OSMLayer osmLayer = new OSMLayer("OSM", - "http://tile.openstreetmap.org/${z}/${x}/${y}.png", 19); - map.addLayer(osmLayer); - - map.addControl(new OverviewMapControl()); - - // map.addLayer(new BingLayer("Bing Aerial", BingLayer.AERIAL)); + private GeoJcrMapper geoJcrMapper; + + public MapViewer createMapControl(Node context,Composite parent) { + return new OpenLayersMapViewer(context,geoJcrMapper,parent); + } - MapContextAdapter mapContextAdapter = new MapContextAdapter( - mapContextProvider.getMapContext(), map); - // FIXME: find a better way to register it - openLayersWidget.setData(mapContextAdapter); - // openLayersWidget.addMouseListener(mapContextAdapter); - return openLayersWidget; + protected void setGeoJcrMapper(GeoJcrMapper geoJcrMapper) { + this.geoJcrMapper = geoJcrMapper; } + } diff --git a/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapViewer.java b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapViewer.java new file mode 100644 index 000000000..1228611fe --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui.rap.openlayers/src/main/java/org/argeo/gis/ui/rap/openlayers/OpenLayersMapViewer.java @@ -0,0 +1,242 @@ +package org.argeo.gis.ui.rap.openlayers; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeSet; + +import javax.jcr.Node; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.geotools.GeoToolsUtils; +import org.argeo.geotools.jcr.GeoJcrMapper; +import org.argeo.gis.ui.AbstractMapViewer; +import org.argeo.gis.ui.MapViewerListener; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.geotools.data.FeatureSource; +import org.geotools.feature.FeatureCollection; +import org.geotools.feature.FeatureIterator; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.polymap.openlayers.rap.widget.OpenLayersWidget; +import org.polymap.openlayers.rap.widget.base.OpenLayersEventListener; +import org.polymap.openlayers.rap.widget.base.OpenLayersObject; +import org.polymap.openlayers.rap.widget.base_types.OpenLayersMap; +import org.polymap.openlayers.rap.widget.base_types.Projection; +import org.polymap.openlayers.rap.widget.controls.KeyboardDefaultsControl; +import org.polymap.openlayers.rap.widget.controls.LayerSwitcherControl; +import org.polymap.openlayers.rap.widget.controls.NavigationControl; +import org.polymap.openlayers.rap.widget.controls.OverviewMapControl; +import org.polymap.openlayers.rap.widget.controls.PanZoomBarControl; +import org.polymap.openlayers.rap.widget.controls.ScaleControl; +import org.polymap.openlayers.rap.widget.controls.SelectFeatureControl; +import org.polymap.openlayers.rap.widget.features.VectorFeature; +import org.polymap.openlayers.rap.widget.geometry.LineStringGeometry; +import org.polymap.openlayers.rap.widget.geometry.PointGeometry; +import org.polymap.openlayers.rap.widget.layers.OSMLayer; +import org.polymap.openlayers.rap.widget.layers.VectorLayer; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Point; + +public class OpenLayersMapViewer extends AbstractMapViewer implements + OpenLayersEventListener { + private final static Log log = LogFactory.getLog(OpenLayersMapViewer.class); + + private final OpenLayersMap map; + + private Map vectorLayers = Collections + .synchronizedMap(new HashMap()); + private Map> featureSources = Collections + .synchronizedMap(new HashMap>()); + + public OpenLayersMapViewer(Node context, GeoJcrMapper geoJcrMapper, + Composite parent) { + super(context, geoJcrMapper); + createControl(parent); + + this.map = ((OpenLayersWidget) getControl()).getMap(); + + // mapContextProvider.getMapContext().addMapLayerListListener(this); + + HashMap payloadMap = new HashMap(); + payloadMap.put("layername", "event.layer.name"); + this.map.events.register(this, "changebaselayer", payloadMap); + payloadMap.put("property", "event.property"); + payloadMap.put("visibility", "event.layer.visibility"); + this.map.events.register(this, "changelayer", payloadMap); + + // WARNING: registering click events on the map hides other events!! + // HashMap mapPayload = new HashMap(); + // mapPayload.put("bbox", map.getJSObjRef() + ".getExtent().toBBOX()"); + // mapPayload.put("lonlat", map.getJSObjRef() + // + ".getLonLatFromViewPortPx(event.xy)"); + // mapPayload.put("x", "event.xy.x"); + // mapPayload.put("y", "event.xy.y"); + // mapPayload.put("button", "event.button"); + // map.events.register(this, "click", mapPayload); + } + + protected void createControl(Composite parent) { + OpenLayersWidget openLayersWidget = new OpenLayersWidget(parent, + SWT.MULTI | SWT.WRAP); + openLayersWidget.setLayoutData(new GridData(GridData.FILL_BOTH)); + + OpenLayersMap map = openLayersWidget.getMap(); + map.setProjection(new Projection("EPSG:900913")); + map.setDisplayProjection(new Projection("EPSG:4326")); + map.setUnits("m"); + + map.addControl(new LayerSwitcherControl()); + NavigationControl navigationControl = new NavigationControl(); + navigationControl.setObjAttr("handleRightClicks", true); + navigationControl.setObjAttr("zoomBoxEnabled", true); + map.addControl(navigationControl); + map.addControl(new KeyboardDefaultsControl()); + map.addControl(new PanZoomBarControl()); + map.addControl(new ScaleControl()); + + // WMSLayer baseLayer = new WMSLayer("argeo_dev", + // "https://dev.argeo.org/geoserver/wms?", + // "naturalearth:10m_admin_0_countries"); + + OSMLayer osmLayer = new OSMLayer("OSM", + "http://tile.openstreetmap.org/${z}/${x}/${y}.png", 19); + map.addLayer(osmLayer); + + map.addControl(new OverviewMapControl()); + + setControl(openLayersWidget); + } + + /* + * OPENLAYERS MAP + */ + + public void process_event(OpenLayersObject source, String eventName, + HashMap payload) { + if (eventName.equals("beforefeatureadded")) { + if (log.isDebugEnabled()) + log.debug("before feature added on layer '" + + payload.get("layername") + "' x=" + payload.get("x") + + "' y=" + payload.get("y")); + } else if (eventName.equals("afterfeatureadded")) { + if (log.isDebugEnabled()) + log.debug("after feature added on layer '" + + payload.get("layername") + "' x=" + payload.get("x") + + "' y=" + payload.get("y")); + } else if (eventName.equals("featureselected")) { + if (log.isDebugEnabled()) + log.debug("feature selected " + payload); + String layerId = payload.get("layerId"); + String featureId = payload.get("featureId"); + if (!getSelected().containsKey(layerId)) + getSelected().put(layerId, new TreeSet()); + getSelected().get(layerId).add(featureId); + + for (MapViewerListener listener : getListeners()) + listener.featureSelected(layerId, featureId); + } else if (eventName.equals("featureunselected")) { + if (log.isDebugEnabled()) + log.debug("feature unselected " + payload); + String layerId = payload.get("layerId"); + String featureId = payload.get("featureId"); + if (getSelected().containsKey(layerId)) + getSelected().get(layerId).remove(featureId); + for (MapViewerListener listener : getListeners()) + listener.featureUnselected(layerId, featureId); + + } else if (log.isDebugEnabled()) + log.debug("Unknown event '" + eventName + "' from " + + source.getClass().getName() + " (" + source.getJSObjRef() + + ")" + " : " + payload); + + } + + @Override + protected void addFeatureSource(String path, + FeatureSource featureSource) { + FeatureIterator featureIterator = null; + try { + String layerId = path; + VectorLayer vectorLayer = new VectorLayer(featureSource.getName() + .toString()); + vectorLayer.setObjAttr("id", layerId); + vectorLayers.put(layerId, vectorLayer); + featureSources.put(layerId, featureSource); + + // selection + HashMap selectPayload = new HashMap(); + selectPayload.put("featureId", "event.feature.id"); + selectPayload.put("geometry", "event.feature.geometry"); + selectPayload.put("layerId", "event.feature.layer.id"); + vectorLayer.events.register(this, "featureselected", selectPayload); + + HashMap unselectPayload = new HashMap(); + unselectPayload.put("featureId", "event.feature.id"); + unselectPayload.put("geometry", "event.feature.geometry"); + unselectPayload.put("layerId", "event.feature.layer.id"); + vectorLayer.events.register(this, "featureunselected", + unselectPayload); + SelectFeatureControl mfc = new SelectFeatureControl(vectorLayer, 0); + // mfc.events.register(this, SelectFeatureControl.EVENT_HIGHLIGHTED, + // unselectPayload); + // mfc.events.register(this, + // SelectFeatureControl.EVENT_UNHIGHLIGHTED, + // unselectPayload); + map.addControl(mfc); + mfc.setMultiple(true); + mfc.setRenderIntent("temporary"); + mfc.activate(); + + FeatureCollection featureCollection = featureSource + .getFeatures(); + featureIterator = featureCollection.features(); + // TODO make this interruptible since it can easily block with huge + // data + while (featureIterator.hasNext()) { + SimpleFeature feature = featureIterator.next(); + Geometry geom = (Geometry) feature.getDefaultGeometry(); + if (log.isTraceEnabled()) + log.trace("Feature " + feature.getID() + ", " + + geom.getClass().getName()); + // log.debug(" Geom: " + geom.getClass() + ", centroid=" + // + geom.getCentroid()); + if (geom instanceof Point) { + Point mp = (Point) geom; + PointGeometry pg = new PointGeometry(mp.getX(), mp.getY()); + VectorFeature vf = new VectorFeature(pg); + vf.setObjAttr("id", feature.getID()); + vectorLayer.addFeatures(vf); + } else if (geom instanceof MultiPolygon) { + MultiPolygon mp = (MultiPolygon) geom; + List points = new ArrayList(); + for (Coordinate coo : mp.getCoordinates()) { + // if (log.isDebugEnabled()) + // log.debug(" " + coo.x + "," + coo.y); + points.add(new PointGeometry(coo.x, coo.y)); + } + VectorFeature vf = new VectorFeature( + new LineStringGeometry( + points.toArray(new PointGeometry[points + .size()]))); + vectorLayer.addFeatures(vf); + } + } + map.addLayer(vectorLayer); + } catch (IOException e) { + log.error("Cannot add layer " + featureSource.getName(), e); + } finally { + GeoToolsUtils.closeQuietly(featureIterator); + } + + } +} diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF b/gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF index 7ca7f527d..1ba182679 100644 --- a/gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF +++ b/gis/plugins/org.argeo.gis.ui/META-INF/MANIFEST.MF @@ -21,6 +21,9 @@ Import-Package: javax.jcr;version="2.0.0", org.argeo.geotools.jcr, org.argeo.jcr, org.argeo.jcr.gis, + org.eclipse.ui.forms, + org.eclipse.ui.forms.editor, + org.eclipse.ui.forms.widgets, org.geotools.data, org.geotools.map, org.geotools.map.event, diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml b/gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml index 52746358d..759f66cc3 100644 --- a/gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml +++ b/gis/plugins/org.argeo.gis.ui/META-INF/spring/commands.xml @@ -5,10 +5,12 @@ http://www.springframework.org/schema/beans/spring-beans.xsd"> + + diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/spring/geojcr.xml b/gis/plugins/org.argeo.gis.ui/META-INF/spring/geojcr.xml deleted file mode 100644 index 8b194c0a7..000000000 --- a/gis/plugins/org.argeo.gis.ui/META-INF/spring/geojcr.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml b/gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml index 711b80acf..17147744c 100644 --- a/gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml +++ b/gis/plugins/org.argeo.gis.ui/META-INF/spring/osgi.xml @@ -7,13 +7,10 @@ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - - - + + \ No newline at end of file diff --git a/gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml b/gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml index c75bce9b7..0259d22c3 100644 --- a/gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml +++ b/gis/plugins/org.argeo.gis.ui/META-INF/spring/views.xml @@ -12,7 +12,6 @@ - diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/AbstractMapViewer.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/AbstractMapViewer.java new file mode 100644 index 000000000..d767f2277 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/AbstractMapViewer.java @@ -0,0 +1,106 @@ +package org.argeo.gis.ui; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; + +import org.argeo.ArgeoException; +import org.argeo.geotools.jcr.GeoJcrMapper; +import org.argeo.jcr.CollectionNodeIterator; +import org.argeo.jcr.gis.GisTypes; +import org.eclipse.swt.widgets.Composite; +import org.geotools.data.FeatureSource; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; + +/** + * Logic of a map viewer which is independent from a particular map display + * implementation. + */ +public abstract class AbstractMapViewer implements MapViewer { + private final Node context; + private final GeoJcrMapper geoJcrMapper; + + private Composite control; + private Map> selected = new HashMap>(); + + private Set listeners = Collections + .synchronizedSet(new HashSet()); + + protected abstract void addFeatureSource(String path, + FeatureSource featureSource); + + public AbstractMapViewer(Node context, GeoJcrMapper geoJcrMapper) { + super(); + this.context = context; + this.geoJcrMapper = geoJcrMapper; + } + + public void addLayer(Node layer) { + try { + if (layer.isNodeType(GisTypes.GIS_FEATURE_SOURCE)) { + addFeatureSource(layer.getPath(), + geoJcrMapper.getFeatureSource(layer)); + } + } catch (Exception e) { + throw new ArgeoException("Cannot add layer " + layer, e); + } + + } + + public NodeIterator getSelectedFeatures() { + try { + List nodes = new ArrayList(); + for (String layerId : selected.keySet()) { + Set featureIds = selected.get(layerId); + Node featureSource = context.getSession().getNode(layerId); + for (String featureId : featureIds) { + Node featureNode = geoJcrMapper.getFeatureNode( + featureSource, featureId); + nodes.add(featureNode); + } + } + return new CollectionNodeIterator(nodes); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get selected features from " + + context, e); + } + } + + public void addMapViewerListener(MapViewerListener listener) { + listeners.add(listener); + } + + public void removeMapViewerListener(MapViewerListener listener) { + listeners.remove(listener); + } + + protected Node getContext() { + return context; + } + + protected Map> getSelected() { + return selected; + } + + protected Set getListeners() { + return listeners; + } + + protected void setControl(Composite control) { + this.control = control; + } + + public Composite getControl() { + return control; + } + +} diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapContextProvider.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapContextProvider.java index 1c7e2a5f2..5c99dc3bf 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapContextProvider.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapContextProvider.java @@ -1,7 +1,12 @@ package org.argeo.gis.ui; -import org.geotools.map.MapContext; +import javax.jcr.Node; public interface MapContextProvider { - public MapContext getMapContext(); + //public MapContext getMapContext(); + + public void addLayer(Node layer); + + public void featureSelected(String layerId, String featureId); + public void featureUnselected(String layerId, String featureId); } diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapControlCreator.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapControlCreator.java index 21af4b136..ef58bde51 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapControlCreator.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapControlCreator.java @@ -1,9 +1,10 @@ package org.argeo.gis.ui; +import javax.jcr.Node; + import org.eclipse.swt.widgets.Composite; public interface MapControlCreator { - /** Creates a map control based on this parent and this map context */ - public Composite createMapControl(Composite parent, - MapContextProvider mapContextProvider); + /** Creates a map control based on this parent and this context */ + public MapViewer createMapControl(Node context, Composite parent); } diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapViewer.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapViewer.java new file mode 100644 index 000000000..701ef59a2 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapViewer.java @@ -0,0 +1,19 @@ +package org.argeo.gis.ui; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; + +import org.eclipse.swt.widgets.Composite; + +public interface MapViewer { + public void addLayer(Node layer); + + public NodeIterator getSelectedFeatures(); + + public Composite getControl(); + + public void addMapViewerListener(MapViewerListener listener); + + public void removeMapViewerListener(MapViewerListener listener); + +} diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapViewerListener.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapViewerListener.java new file mode 100644 index 000000000..ffb532640 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/MapViewerListener.java @@ -0,0 +1,7 @@ +package org.argeo.gis.ui; + +public interface MapViewerListener { + public void featureSelected(String layerId, String featureId); + + public void featureUnselected(String layerId, String featureId); +} diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddFeatureSources.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddFeatureSources.java index aeb962a80..7c83fad87 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddFeatureSources.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddFeatureSources.java @@ -8,6 +8,7 @@ import java.util.Map; import javax.jcr.Node; import javax.jcr.RepositoryException; +import javax.jcr.Session; import org.argeo.ArgeoException; import org.argeo.eclipse.ui.AbstractTreeContentProvider; @@ -35,6 +36,7 @@ import org.opengis.feature.simple.SimpleFeatureType; public class AddFeatureSources extends AbstractHandler { private GeoJcrMapper geoJcrMapper; + private Session session; public Object execute(ExecutionEvent event) throws ExecutionException { try { @@ -46,7 +48,8 @@ public class AddFeatureSources extends AbstractHandler { for (String alias : featureSources.keySet()) { for (FeatureSource fs : featureSources .get(alias)) { - Node fsNode = geoJcrMapper.getNode(alias, fs); + Node fsNode = geoJcrMapper.getFeatureSourceNode( + session, alias, fs); try { fsNode.getSession().save(); } catch (RepositoryException e) { @@ -67,6 +70,10 @@ public class AddFeatureSources extends AbstractHandler { this.geoJcrMapper = geoJcrMapper; } + protected void setSession(Session session) { + this.session = session; + } + class FeatureSourceChooserDialog extends TitleAreaDialog { private TreeViewer viewer; private Map>> featureSources = new HashMap>>(); diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddLayer.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddLayer.java index 2af873988..3db9127f0 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddLayer.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/AddLayer.java @@ -1,5 +1,7 @@ package org.argeo.gis.ui.commands; +import javax.jcr.Session; + import org.argeo.eclipse.ui.dialogs.Error; import org.argeo.gis.ui.editors.DefaultMapEditor; import org.argeo.gis.ui.editors.MapEditorInput; @@ -7,18 +9,18 @@ import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.ui.handlers.HandlerUtil; -import org.geotools.map.DefaultMapContext; /** Opens a new map editor */ public class AddLayer extends AbstractHandler { private String editorId = DefaultMapEditor.ID; + private Session session; public Object execute(ExecutionEvent event) throws ExecutionException { try { HandlerUtil .getActiveWorkbenchWindow(event) .getActivePage() - .openEditor(new MapEditorInput(new DefaultMapContext()), + .openEditor(new MapEditorInput(session.getRootNode()), editorId); } catch (Exception e) { Error.show("Cannot open editor", e); diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/NewMap.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/NewMap.java index 1a7a5cdf8..f3c5d0c15 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/NewMap.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/commands/NewMap.java @@ -1,5 +1,7 @@ package org.argeo.gis.ui.commands; +import javax.jcr.Session; + import org.argeo.eclipse.ui.dialogs.Error; import org.argeo.gis.ui.editors.DefaultMapEditor; import org.argeo.gis.ui.editors.MapEditorInput; @@ -7,10 +9,10 @@ import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.ui.handlers.HandlerUtil; -import org.geotools.map.DefaultMapContext; /** Opens a new map editor */ public class NewMap extends AbstractHandler { + private Session session; private String editorId = DefaultMapEditor.ID; public Object execute(ExecutionEvent event) throws ExecutionException { @@ -18,7 +20,7 @@ public class NewMap extends AbstractHandler { HandlerUtil .getActiveWorkbenchWindow(event) .getActivePage() - .openEditor(new MapEditorInput(new DefaultMapContext()), + .openEditor(new MapEditorInput(session.getRootNode()), editorId); } catch (Exception e) { Error.show("Cannot open editor", e); @@ -30,4 +32,8 @@ public class NewMap extends AbstractHandler { this.editorId = editorId; } + public void setSession(Session session) { + this.session = session; + } + } diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/DefaultMapEditor.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/DefaultMapEditor.java index e9311b9db..3648b2329 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/DefaultMapEditor.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/DefaultMapEditor.java @@ -1,8 +1,9 @@ package org.argeo.gis.ui.editors; -import org.argeo.gis.ui.MapContextProvider; +import javax.jcr.Node; + import org.argeo.gis.ui.MapControlCreator; -import org.argeo.gis.ui.views.LayersView; +import org.argeo.gis.ui.MapViewer; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridLayout; @@ -11,30 +12,27 @@ import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.EditorPart; -import org.geotools.data.FeatureSource; -import org.geotools.map.MapContext; -import org.opengis.feature.simple.SimpleFeature; -import org.opengis.feature.simple.SimpleFeatureType; /** A generic map editor */ -public class DefaultMapEditor extends EditorPart implements MapContextProvider { +public class DefaultMapEditor extends EditorPart { public final static String ID = "org.argeo.gis.ui.defaultMapEditor"; - private MapContext mapContext; - private Composite map; + private Node context; + private MapViewer mapViewer; private MapControlCreator mapControlCreator; @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { - if (input instanceof MapContextProvider) { - mapContext = ((MapContextProvider) input).getMapContext(); + if (input instanceof MapEditorInput) { + // mapContext = ((MapEditorInput) input).getMapContext(); + context = ((MapEditorInput) input).getContext(); setSite(site); setInput(input); setPartName(input.getName()); } else { - throw new PartInitException("Support only " - + MapContextProvider.class + " inputs"); + throw new PartInitException("Support only " + MapEditorInput.class + + " inputs"); } } @@ -45,13 +43,11 @@ public class DefaultMapEditor extends EditorPart implements MapContextProvider { layout.marginHeight = 0; layout.marginWidth = 0; mapArea.setLayout(layout); - map = mapControlCreator.createMapControl(mapArea, this); + mapViewer = mapControlCreator.createMapControl(context, mapArea); } - public void addLayer( - FeatureSource featureSource) { - // TODO: deal with style - mapContext.addLayer(featureSource, null); + public MapViewer getMapViewer() { + return mapViewer; } @Override @@ -74,14 +70,20 @@ public class DefaultMapEditor extends EditorPart implements MapContextProvider { @Override public void setFocus() { - LayersView layersView = (LayersView) getEditorSite() - .getWorkbenchWindow().getActivePage().findView(LayersView.ID); - layersView.setMapContext(getMapContext()); - map.setFocus(); + // LayersView layersView = (LayersView) getEditorSite() + // .getWorkbenchWindow().getActivePage().findView(LayersView.ID); + // layersView.setMapContext(getMapContext()); + mapViewer.getControl().setFocus(); } - public MapContext getMapContext() { - return mapContext; + public void featureSelected(String layerId, String featureId) { + // TODO Auto-generated method stub + + } + + public void featureUnselected(String layerId, String featureId) { + // TODO Auto-generated method stub + } public void setMapControlCreator(MapControlCreator mapControlCreator) { diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/MapEditorInput.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/MapEditorInput.java index 7deb74c8e..584138a0d 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/MapEditorInput.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/MapEditorInput.java @@ -1,35 +1,34 @@ package org.argeo.gis.ui.editors; -import org.argeo.gis.ui.MapContextProvider; +import javax.jcr.Node; + import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IPersistableElement; -import org.geotools.map.MapContext; -public class MapEditorInput implements IEditorInput, MapContextProvider { - private final MapContext mapContext; +public class MapEditorInput implements IEditorInput { + private final Node context; - public MapEditorInput(MapContext mapContext) { - this.mapContext = mapContext; + public MapEditorInput(Node mapContext) { + this.context = mapContext; } - public MapContext getMapContext() { - return mapContext; + public Node getContext() { + return context; } public String getName() { - return mapContext.getTitle() != null ? mapContext.getTitle() : ""; + return context.toString(); } public String getToolTipText() { - return mapContext.getAbstract() != null ? mapContext.getAbstract() - : mapContext.getTitle() != null ? mapContext.getTitle() : ""; + return context.toString(); } @SuppressWarnings("rawtypes") public Object getAdapter(Class adapter) { - if (MapContext.class.isAssignableFrom(adapter)) - return mapContext; + if (Node.class.isAssignableFrom(adapter)) + return context; return null; } diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/MapFormPage.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/MapFormPage.java new file mode 100644 index 000000000..c84816571 --- /dev/null +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/editors/MapFormPage.java @@ -0,0 +1,72 @@ +package org.argeo.gis.ui.editors; + +import javax.jcr.Node; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.gis.ui.MapControlCreator; +import org.argeo.gis.ui.MapViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** A form editor page to edit geographical data. */ +public class MapFormPage extends FormPage { + private final static Log log = LogFactory.getLog(MapFormPage.class); + + private Node context; + private MapViewer mapViewer; + private MapControlCreator mapControlCreator; + + public MapFormPage(FormEditor editor, String id, String title, + Node context, MapControlCreator mapControlCreator) { + super(editor, id, title); + this.context = context; + this.mapControlCreator = mapControlCreator; + } + + @Override + protected void createFormContent(IManagedForm managedForm) { + Composite parent = managedForm.getForm().getBody(); + parent.setLayout(new FillLayout()); + + FormToolkit tk = managedForm.getToolkit(); + + Composite mapArea = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + mapArea.setLayout(layout); + mapViewer = mapControlCreator.createMapControl(context, mapArea); + tk.adapt(mapViewer.getControl()); + } + + public void featureSelected(String layerId, String featureId) { + if (log.isDebugEnabled()) + log.debug("Selected feature '" + featureId + "' of layer '" + + layerId + "'"); + + } + + public void featureUnselected(String layerId, String featureId) { + if (log.isDebugEnabled()) + log.debug("Unselected feature '" + featureId + "' of layer '" + + layerId + "'"); + + } + + public void setFocus() { + super.setFocus(); + mapViewer.getControl().setFocus(); + } + + public MapViewer getMapViewer() { + return mapViewer; + } + +} diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/DataStoresView.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/DataStoresView.java index 7bb008d6f..17ae43165 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/DataStoresView.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/DataStoresView.java @@ -50,7 +50,7 @@ public class DataStoresView extends ViewPart implements IDoubleClickListener { .getFeatureSource(); IEditorPart ed = getSite().getWorkbenchWindow().getActivePage().getActiveEditor(); if(ed instanceof DefaultMapEditor){ - ((DefaultMapEditor)ed).addLayer(featureSource); +// ((DefaultMapEditor)ed).addLayer(featureSource); } } } diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java index 76ea5dd56..a534d4745 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/FeatureSourcesView.java @@ -6,8 +6,8 @@ import javax.jcr.Session; import org.argeo.ArgeoException; import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider; -import org.argeo.geotools.jcr.GeoJcrMapper; import org.argeo.gis.ui.editors.DefaultMapEditor; +import org.argeo.gis.ui.editors.MapFormPage; import org.argeo.jcr.gis.GisTypes; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; @@ -17,10 +17,9 @@ import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.IFormPage; import org.eclipse.ui.part.ViewPart; -import org.geotools.data.FeatureSource; -import org.opengis.feature.simple.SimpleFeature; -import org.opengis.feature.simple.SimpleFeatureType; public class FeatureSourcesView extends ViewPart implements IDoubleClickListener { @@ -32,14 +31,14 @@ public class FeatureSourcesView extends ViewPart implements private TreeViewer viewer; - private GeoJcrMapper geoJcrMapper; - @Override public void createPartControl(Composite parent) { viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); String[] basePaths = { dataStoresBasePath }; - viewer.setContentProvider(new SimpleNodeContentProvider(session, - basePaths)); + SimpleNodeContentProvider sncp = new SimpleNodeContentProvider(session, + basePaths); + sncp.setMkdirs(true); + viewer.setContentProvider(sncp); viewer.setLabelProvider(new MapsLabelProvider()); viewer.setInput(getViewSite()); viewer.addDoubleClickListener(this); @@ -52,18 +51,22 @@ public class FeatureSourcesView extends ViewPart implements if (obj instanceof Node) { Node node = (Node) obj; try { - if (!node.getPrimaryNodeType().isNodeType( - GisTypes.GIS_FEATURE_SOURCE)) + if (!node.isNodeType(GisTypes.GIS_FEATURE_SOURCE)) return; } catch (RepositoryException e) { throw new ArgeoException("Cannot check type of " + node, e); } - FeatureSource featureSource = geoJcrMapper - .getFeatureSource(node); IEditorPart ed = getSite().getWorkbenchWindow().getActivePage() .getActiveEditor(); if (ed instanceof DefaultMapEditor) { - ((DefaultMapEditor) ed).addLayer(featureSource); + ((DefaultMapEditor) ed).getMapViewer().addLayer(node); + } else if (ed instanceof FormEditor) { + IFormPage activePage = ((FormEditor) ed) + .getActivePageInstance(); + if (activePage instanceof MapFormPage) { + ((MapFormPage) activePage).getMapViewer() + .addLayer(node); + } } } @@ -71,10 +74,6 @@ public class FeatureSourcesView extends ViewPart implements } - public void setGeoJcrMapper(GeoJcrMapper geoJcrMapper) { - this.geoJcrMapper = geoJcrMapper; - } - @Override public void setFocus() { viewer.getTree().setFocus(); diff --git a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java index 096f03657..e2d2fb063 100644 --- a/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java +++ b/gis/plugins/org.argeo.gis.ui/src/main/java/org/argeo/gis/ui/views/LayersView.java @@ -92,7 +92,7 @@ public class LayersView extends ViewPart implements MapLayerListListener { MapContextNode mapContextNode = (MapContextNode) element; return mapContextNode.getMapContext().getLayers(); } else if (element instanceof MapLayer) { - // MapLayer mapLayer = (MapLayer) element; + MapLayer mapLayer = (MapLayer) element; } else if (element instanceof TreeParent) { return ((TreeParent) element).getChildren(); 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 index 2f62c8bf7..e1c3db1f1 100644 --- 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 @@ -38,7 +38,6 @@ import org.opengis.filter.identity.FeatureId; import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrMapper.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrMapper.java index f8fe50288..b5bf0036f 100644 --- a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrMapper.java +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/GeoJcrMapper.java @@ -4,22 +4,27 @@ import java.util.List; import java.util.Map; import javax.jcr.Node; +import javax.jcr.Session; import org.geotools.data.FeatureSource; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; public interface GeoJcrMapper { - /** Create it if it does not exist */ - public Node getNode(String dataStoreAlias, - FeatureSource featureSource, - SimpleFeature feature); + // public Node getNode(String dataStoreAlias, + // FeatureSource featureSource, + // SimpleFeature feature); public Map>> getPossibleFeatureSources(); - public Node getNode(String dataStoreAlias, + public Node getFeatureSourceNode(Session session, String dataStoreAlias, FeatureSource featureSource); + // public Node getNode(String dataStoreAlias, + // FeatureSource featureSource); + + public Node getFeatureNode(Node featureSource, String featureId); + public FeatureSource getFeatureSource( Node node); 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 a055a4238..d36618705 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 @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +import javax.jcr.Binary; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -15,14 +16,19 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; import org.argeo.geotools.GeoToolsConstants; +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.FeatureSource; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.Name; +import com.vividsolutions.jts.geom.Geometry; + public class SimpleGeoJcrMapper implements GeoJcrMapper { private final static Log log = LogFactory.getLog(SimpleGeoJcrMapper.class); @@ -31,7 +37,7 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { private Map registeredDataStores = Collections .synchronizedSortedMap(new TreeMap()); - private Session session; + // private Session session; public Map>> getPossibleFeatureSources() { Map>> res = new TreeMap>>(); @@ -61,44 +67,82 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { return res; } - public Node getNode(String dataStoreAlias, - FeatureSource featureSource, - SimpleFeature feature) { - StringBuffer pathBuf = new StringBuffer(dataStoresBasePath); - pathBuf.append('/').append(dataStoreAlias); - pathBuf.append('/').append(featureSource.getName()); - - // TODO: use centroid or bbox to create some depth - // Geometry geometry = (Geometry)feature.getDefaultGeometry(); - // Point centroid = geometry.getCentroid(); - - pathBuf.append('/').append(feature.getID()); - - String path = pathBuf.toString(); + // public Node getNode(String dataStoreAlias, + // FeatureSource featureSource, + // SimpleFeature feature) { + // StringBuffer pathBuf = new StringBuffer(dataStoresBasePath); + // pathBuf.append('/').append(dataStoreAlias); + // pathBuf.append('/').append(featureSource.getName()); + // + // // TODO: use centroid or bbox to create some depth + // // Geometry geometry = (Geometry)feature.getDefaultGeometry(); + // // Point centroid = geometry.getCentroid(); + // + // pathBuf.append('/').append(feature.getID()); + // + // String path = pathBuf.toString(); + // try { + // if (session.itemExists(path)) + // return session.getNode(path); + // else + // return JcrUtils.mkdirs(session, path); + // } catch (RepositoryException e) { + // throw new ArgeoException("Cannot get feature node for " + path, e); + // } + // } + + public Node getFeatureNode(Node featureSourceNode, String featureId) { + Binary bbox = null; + Binary centroid = null; try { - if (session.itemExists(path)) - return session.getNode(path); - else - return JcrUtils.mkdirs(session, path); + if (!featureSourceNode.hasNode(featureId)) { + FeatureSource featureSource = getFeatureSource(featureSourceNode); + SimpleFeature feature = GeoToolsUtils.querySingleFeature( + featureSource, featureId); + 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()); + + bbox = JtsJcrUtils.writeWkb(featureNode.getSession(), + geometry.getEnvelope()); + featureNode.setProperty(GisNames.GIS_BBOX, bbox); + centroid = JtsJcrUtils.writeWkb(featureNode.getSession(), + geometry.getCentroid()); + featureNode.setProperty(GisNames.GIS_CENTROID, centroid); + featureSourceNode.getSession().save(); + return featureNode; + } else { + return featureSourceNode.getNode(featureId); + } } catch (RepositoryException e) { - throw new ArgeoException("Cannot get feature node for " + path, e); + throw new ArgeoException("Cannot get feature node for feature " + + featureId + " from " + featureSourceNode, e); + } finally { + JcrUtils.closeQuietly(bbox); + JcrUtils.closeQuietly(centroid); } } - protected Node getNode(String dataStoreAlias) { + protected Node getNode(Session session, String dataStoreAlias) { try { Node dataStores; - if (!session.itemExists(dataStoresBasePath)) + if (!session.itemExists(dataStoresBasePath)) { dataStores = JcrUtils.mkdirs(session, dataStoresBasePath); - else + dataStores.getSession().save(); + } else dataStores = session.getNode(dataStoresBasePath); Node dataStoreNode; if (dataStores.hasNode(dataStoreAlias)) dataStoreNode = dataStores.getNode(dataStoreAlias); - else + else { dataStoreNode = dataStores.addNode(dataStoreAlias, GisTypes.GIS_DATA_STORE); + dataStoreNode.getSession().save(); + } return dataStoreNode; } catch (RepositoryException e) { throw new ArgeoException("Cannot get node for data store " @@ -106,15 +150,19 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { } } - public Node getNode(String dataStoreAlias, + public Node getFeatureSourceNode(Session session, String dataStoreAlias, FeatureSource featureSource) { try { String name = featureSource.getName().toString(); - Node dataStoreNode = getNode(dataStoreAlias); + Node dataStoreNode = getNode(session, dataStoreAlias); if (dataStoreNode.hasNode(name)) return dataStoreNode.getNode(name); - else - return dataStoreNode.addNode(name, GisTypes.GIS_FEATURE_SOURCE); + else { + Node featureSourceNode = dataStoreNode.addNode(name); + featureSourceNode.addMixin(GisTypes.GIS_FEATURE_SOURCE); + featureSourceNode.getSession().save(); + return featureSourceNode; + } } catch (RepositoryException e) { throw new ArgeoException( "Cannot get feature source node for data store " @@ -131,7 +179,8 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { if (!registeredDataStores.containsKey(dataStoreNode.getName())) throw new ArgeoException("No data store registered under " + dataStoreNode); - DataStore dataStore = registeredDataStores.get(dataStoreNode.getName()); + DataStore dataStore = registeredDataStores.get(dataStoreNode + .getName()); return dataStore.getFeatureSource(node.getName()); } catch (Exception e) { throw new ArgeoException("Cannot find feature source " + node, e); @@ -165,8 +214,8 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { .remove(properties.get(GeoToolsConstants.ALIAS_KEY)); } - public void setSession(Session session) { - this.session = session; - } + // public void setSession(Session session) { + // this.session = session; + // } } diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/jts/jcr/JtsJcrUtils.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/jts/jcr/JtsJcrUtils.java index 391f66c59..f649f6687 100644 --- a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/jts/jcr/JtsJcrUtils.java +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/jts/jcr/JtsJcrUtils.java @@ -1,25 +1,19 @@ package org.argeo.jts.jcr; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.InputStream; import javax.jcr.Binary; -import javax.jcr.Node; -import javax.jcr.PathNotFoundException; import javax.jcr.Property; -import javax.jcr.RepositoryException; +import javax.jcr.Session; import org.apache.commons.io.IOUtils; import org.argeo.ArgeoException; import org.argeo.jcr.JcrUtils; -import org.argeo.jcr.gis.GisNames; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.io.InputStreamInStream; -import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKBReader; import com.vividsolutions.jts.io.WKBWriter; @@ -53,21 +47,20 @@ public class JtsJcrUtils { } } - public final static void writeWkb(Property property, Geometry geometry) { + /** The returned binary should be disposed by the caller */ + public final static Binary writeWkb(Session session, Geometry geometry) { Binary wkbBinary = null; InputStream in = null; try { WKBWriter wkbWriter = wkbWriters.get(); byte[] arr = wkbWriter.write(geometry); in = new ByteArrayInputStream(arr); - wkbBinary = property.getSession().getValueFactory() - .createBinary(in); - property.setValue(wkbBinary); + wkbBinary = session.getValueFactory().createBinary(in); + return wkbBinary; } catch (Exception e) { - throw new ArgeoException("Cannot write WKB to " + property, e); + throw new ArgeoException("Cannot write WKB", e); } finally { IOUtils.closeQuietly(in); - JcrUtils.closeQuietly(wkbBinary); } } } diff --git a/security/dep/org.argeo.security.dep.ads/pom.xml b/security/dep/org.argeo.security.dep.ads/pom.xml index f9e8999e0..7dc555376 100644 --- a/security/dep/org.argeo.security.dep.ads/pom.xml +++ b/security/dep/org.argeo.security.dep.ads/pom.xml @@ -13,36 +13,42 @@ org.argeo.commons.security - org.argeo.security.dep.ldap + org.argeo.security.core ${version.argeo-commons} - pom - org.argeo.commons.server - org.argeo.server.dep.ads + org.argeo.commons.security + org.argeo.security.ldap ${version.argeo-commons} - pom - - - org.argeo.commons.server - org.argeo.server.ads.server + org.argeo.commons.security + org.argeo.security.services ${version.argeo-commons} org.argeo.commons.security - org.argeo.security.services + org.argeo.security.manager.ldap ${version.argeo-commons} + org.argeo.commons.security - org.argeo.security.ldap + org.argeo.security.dep.ldap ${version.argeo-commons} + pom - org.argeo.commons.security - org.argeo.security.manager.ldap + org.argeo.commons.server + org.argeo.server.dep.ads + ${version.argeo-commons} + pom + + + + + org.argeo.commons.server + org.argeo.server.ads.server ${version.argeo-commons} diff --git a/server/dep/org.argeo.server.dep.jackrabbit.server/pom.xml b/server/dep/org.argeo.server.dep.jackrabbit.server/pom.xml index 927608a18..dec2f3638 100644 --- a/server/dep/org.argeo.server.dep.jackrabbit.server/pom.xml +++ b/server/dep/org.argeo.server.dep.jackrabbit.server/pom.xml @@ -167,19 +167,15 @@ org.xmlpull com.springsource.org.xmlpull - - org.argeo.commons.server org.argeo.server.dep.javax ${version.argeo-commons} pom - test org.apache.xmlcommons com.springsource.org.apache.xmlcommons - test diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java new file mode 100644 index 000000000..ac3cce9fd --- /dev/null +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java @@ -0,0 +1,24 @@ +package org.argeo.jackrabbit; + +import java.util.Map; + +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.RepositoryFactory; + +import org.argeo.jcr.ArgeoJcrConstants; +import org.argeo.jcr.DefaultRepositoryRegister; + +public class JackrabbitRepositoryFactory extends DefaultRepositoryRegister + implements RepositoryFactory, ArgeoJcrConstants { + + @SuppressWarnings("rawtypes") + public Repository getRepository(Map parameters) throws RepositoryException { + String alias; + if (parameters.containsKey(JCR_REPOSITORY_ALIAS)) { + alias = parameters.get(JCR_REPOSITORY_ALIAS).toString(); + } + return null; + } + +} diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoJcrConstants.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoJcrConstants.java index 1202268ea..458246ef4 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoJcrConstants.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoJcrConstants.java @@ -1,8 +1,9 @@ package org.argeo.jcr; -/** JCR related constants*/ +/** JCR related constants */ public interface ArgeoJcrConstants { public final static String JCR_REPOSITORY_ALIAS = "argeo.jcr.repository.alias"; + public final static String JCR_REPOSITORY_URI = "argeo.jcr.repository.uri"; } diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoNames.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoNames.java index 73b2046cc..ab6c02123 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoNames.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoNames.java @@ -3,5 +3,8 @@ package org.argeo.jcr; /** JCR names in the http://www.argeo.org/argeo namespace */ public interface ArgeoNames { public final static String ARGEO_ = "argeo:"; - public final static String ARGEO_USER_ID = ARGEO_ + "userID"; + + public final static String ARGEO_URI = "argeo:uri"; + public final static String ARGEO_LINK = "argeo:link"; + public final static String ARGEO_USER_ID = "argeo:userID"; } diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoTypes.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoTypes.java index 8371923c6..56ef1570a 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoTypes.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoTypes.java @@ -2,6 +2,7 @@ package org.argeo.jcr; /** JCR types in the http://www.argeo.org/argeo namespace */ public interface ArgeoTypes { + public final static String ARGEO_LINKS = "argeo:links"; public final static String ARGEO_HOME = "argeo:home"; public final static String ARGEO_USER_HOME = "argeo:userHome"; } diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/CollectionNodeIterator.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/CollectionNodeIterator.java new file mode 100644 index 000000000..b4124eea5 --- /dev/null +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/CollectionNodeIterator.java @@ -0,0 +1,61 @@ +package org.argeo.jcr; + +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; + +/** Wraps a collection of nodes in order to read it as a {@link NodeIterator} */ +public class CollectionNodeIterator implements NodeIterator { + private final Long collectionSize; + private final Iterator iterator; + private Integer position = 0; + + public CollectionNodeIterator(Collection nodes) { + super(); + this.collectionSize = (long) nodes.size(); + this.iterator = nodes.iterator(); + } + + public void skip(long skipNum) { + if (skipNum < 0) + throw new IllegalArgumentException( + "Skip count has to be positive: " + skipNum); + + for (long i = 0; i < skipNum; i++) { + if (!hasNext()) + throw new NoSuchElementException("Last element past (position=" + + getPosition() + ")"); + nextNode(); + } + } + + public long getSize() { + return collectionSize; + } + + public long getPosition() { + return position; + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public Object next() { + return nextNode(); + } + + public void remove() { + iterator.remove(); + } + + public Node nextNode() { + Node node = iterator.next(); + position++; + return node; + } + +} diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrResourceAdapter.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrResourceAdapter.java index d391a69e0..583995057 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrResourceAdapter.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrResourceAdapter.java @@ -36,8 +36,8 @@ import org.argeo.ArgeoException; import org.springframework.core.io.Resource; /** - * Bridge Spring resources and JCR folder / files semantics (nt:folder / nt:file), - * supporting versioning as well. + * Bridge Spring resources and JCR folder / files semantics (nt:folder / + * nt:file), supporting versioning as well. */ public class JcrResourceAdapter { private final static Log log = LogFactory.getLog(JcrResourceAdapter.class); @@ -57,7 +57,7 @@ public class JcrResourceAdapter { } public void mkdirs(String path) { - JcrUtils.mkdirs(session(), path, "nt:folder", versioning); + JcrUtils.mkdirs(session(), path, "nt:folder", "nt:folder", versioning); } public void create(String path, Resource file, String mimeType) { diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java index 6afd8e13c..6871e60c7 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java @@ -16,6 +16,8 @@ package org.argeo.jcr; +import java.net.MalformedURLException; +import java.net.URL; import java.text.DateFormat; import java.text.ParseException; import java.util.Calendar; @@ -100,6 +102,27 @@ public class JcrUtils { return dateAsPath(cal, false); } + /** + * Creates a deep path based on a URL: + * http://subdomain.example.com/to/content?args => + * com/example/subdomain/to/content + */ + public static String urlAsPath(String url) { + try { + URL u = new URL(url); + StringBuffer path = new StringBuffer(url.length()); + // invert host + String[] hostTokens = u.getHost().split("\\."); + for (int i = hostTokens.length - 1; i >= 0; i--) + path.append(hostTokens[i]).append('/'); + // we don't put port since it may not always be there and may change + path.append(u.getPath()); + return path.toString(); + } catch (MalformedURLException e) { + throw new ArgeoException("Cannot generate URL path for " + url, e); + } + } + /** * The provided data as a path ('/' at the end, not the beginning) * @@ -168,12 +191,30 @@ public class JcrUtils { /** Creates the nodes making path, if they don't exist. */ public static Node mkdirs(Session session, String path) { - return mkdirs(session, path, null, false); + return mkdirs(session, path, null, null, false); } - /** Creates the nodes making path, if they don't exist. */ + /** + * @deprecated use {@link #mkdirs(Session, String, String, String, Boolean)} + * instead. + */ + @Deprecated public static Node mkdirs(Session session, String path, String type, Boolean versioning) { + return mkdirs(session, path, type, type, false); + } + + /** + * @param type + * the type of the leaf node + */ + public static Node mkdirs(Session session, String path, String type) { + return mkdirs(session, path, type, null, false); + } + + /** Creates the nodes making path, if they don't exist. */ + public static Node mkdirs(Session session, String path, String type, + String intermediaryNodeType, Boolean versioning) { try { if (path.equals('/')) return session.getRootNode(); @@ -198,8 +239,11 @@ public class JcrUtils { String part = st.nextToken(); current.append(part).append('/'); if (!session.itemExists(current.toString())) { - if (type != null) + if (!st.hasMoreTokens() && type != null) currentNode = currentNode.addNode(part, type); + else if (st.hasMoreTokens() && intermediaryNodeType != null) + currentNode = currentNode.addNode(part, + intermediaryNodeType); else currentNode = currentNode.addNode(part); if (versioning) @@ -495,9 +539,9 @@ public class JcrUtils { public static String normalize(String name) { return name.replace(':', '_'); } - - public static void closeQuietly(Binary binary){ - if(binary==null) + + public static void closeQuietly(Binary binary) { + if (binary == null) return; binary.dispose(); } diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java index 981caf98a..3bd1bc6b2 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisTypes.java @@ -11,4 +11,6 @@ public interface GisTypes { public final static String GIS_DATA_STORE = "gis:dataStore"; public final static String GIS_FEATURE_SOURCE = "gis:featureSource"; + public final static String GIS_FEATURE = "gis:feature"; + public final static String GIS_RELATED_FEATURE = "gis:feature"; } diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/CaManager.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/CaManager.java new file mode 100644 index 000000000..ffa434fc1 --- /dev/null +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/CaManager.java @@ -0,0 +1,8 @@ +package org.argeo.jcr.security; + +import javax.jcr.Session; + +public class CaManager { +private Session session; + +} diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/SecurityTypes.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/SecurityTypes.java new file mode 100644 index 000000000..c2bde844f --- /dev/null +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/SecurityTypes.java @@ -0,0 +1,5 @@ +package org.argeo.jcr.security; + +public interface SecurityTypes { + public final static String SECURITY_CA = "security:ca"; +} diff --git a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd index aef5458dc..532bcdcaf 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd +++ b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/argeo.cnd @@ -1,5 +1,11 @@ +// GENERIC TYPES NOT AVAILABLE IN JCR +[argeo:links] > mix:created, mix:lastModified +mixin +// URI(s) +- argeo:link (STRING) m * + // HOME DIRECTORIES [argeo:home] > nt:unstructured, mix:created, mix:lastModified orderable diff --git a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd index cc0a1d16b..14c24e7b0 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd +++ b/server/runtime/org.argeo.server.jcr/src/main/resources/org/argeo/jcr/gis/argeo_gis.cnd @@ -36,5 +36,6 @@ mixin [gis:dataStore] > nt:unstructured, mix:title - gis:type (STRING) + * (gis:featureSource) * +// FIXME + * (gis:featureSource) [gis:relatedFeature] > nt:address, gis:located