From 78a52c7ee4e476b3fe366346ed26315f7237a6bb Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Fri, 6 May 2011 14:12:44 +0000 Subject: [PATCH] Improve GIS NEW - bug 31: Add Swing based map viewer in RCP https://bugzilla.argeo.org/show_bug.cgi?id=31 git-svn-id: https://svn.argeo.org/commons/trunk@4511 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../ui/jcr/DefaultNodeLabelProvider.java | 40 +++--- .../org/argeo/eclipse/ui/jcr/JcrImages.java | 18 +++ .../gis/ui/rcp/swing/SwingMapViewer.java | 3 + .../gis/ui/editors/DefaultMapEditor.java | 3 + .../org/argeo/gis/ui/editors/MapFormPage.java | 3 + .../gis/ui/views/FeatureSourcesView.java | 30 ++++- gis/runtime/org.argeo.gis.geotools/pom.xml | 8 +- .../org/argeo/geotools/GeoToolsConstants.java | 8 +- .../org/argeo/geotools/jcr/GeoJcrIndex.java | 17 ++- .../geotools/jcr/SimpleGeoJcrMapper.java | 120 ++++++++++++------ .../geotools/osgi/GisResourcesActivator.java | 67 ++++++++++ .../argeo/jackrabbit/JackrabbitContainer.java | 83 ++++++++---- .../org/argeo/jcr/gis/GisJcrConstants.java | 8 ++ .../main/java/org/argeo/jcr/gis/GisNames.java | 2 + 14 files changed, 324 insertions(+), 86 deletions(-) create mode 100644 eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrImages.java create mode 100644 gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/osgi/GisResourcesActivator.java create mode 100644 server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisJcrConstants.java diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java index b16eda819..109673663 100644 --- a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/DefaultNodeLabelProvider.java @@ -13,16 +13,26 @@ import org.eclipse.swt.graphics.Image; /** Provides reasonable overridable defaults for know JCR types. */ public class DefaultNodeLabelProvider extends ColumnLabelProvider { // Images - public final static Image NODE = JcrUiPlugin.getImageDescriptor( - "icons/node.gif").createImage(); - public final static Image FOLDER = JcrUiPlugin.getImageDescriptor( - "icons/folder.gif").createImage(); - public final static Image FILE = JcrUiPlugin.getImageDescriptor( - "icons/file.gif").createImage(); - public final static Image BINARY = JcrUiPlugin.getImageDescriptor( - "icons/binary.png").createImage(); - public final static Image HOME = JcrUiPlugin.getImageDescriptor( - "icons/home.gif").createImage(); + /** + * @deprecated Use {@link JcrImages#NODE} instead + */ + public final static Image NODE = JcrImages.NODE; + /** + * @deprecated Use {@link JcrImages#FOLDER} instead + */ + public final static Image FOLDER = JcrImages.FOLDER; + /** + * @deprecated Use {@link JcrImages#FILE} instead + */ + public final static Image FILE = JcrImages.FILE; + /** + * @deprecated Use {@link JcrImages#BINARY} instead + */ + public final static Image BINARY = JcrImages.BINARY; + /** + * @deprecated Use {@link JcrImages#HOME} instead + */ + public final static Image HOME = JcrImages.HOME; public String getText(Object element) { try { @@ -66,15 +76,15 @@ public class DefaultNodeLabelProvider extends ColumnLabelProvider { protected Image getImage(Node node) throws RepositoryException { // optimized order if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FILE)) - return FILE; + return JcrImages.FILE; else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER)) - return FOLDER; + return JcrImages.FOLDER; else if (node.getPrimaryNodeType().isNodeType(NodeType.NT_RESOURCE)) - return BINARY; + return JcrImages.BINARY; else if (node.isNodeType(ArgeoTypes.ARGEO_USER_HOME)) - return HOME; + return JcrImages.HOME; else - return NODE; + return JcrImages.NODE; } @Override diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrImages.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrImages.java new file mode 100644 index 000000000..c99e3f572 --- /dev/null +++ b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrImages.java @@ -0,0 +1,18 @@ +package org.argeo.eclipse.ui.jcr; + +import org.eclipse.swt.graphics.Image; + +/** Shared icons. */ +public class JcrImages { + public final static Image NODE = JcrUiPlugin.getImageDescriptor( + "icons/node.gif").createImage(); + public final static Image FOLDER = JcrUiPlugin.getImageDescriptor( + "icons/folder.gif").createImage(); + public final static Image FILE = JcrUiPlugin.getImageDescriptor( + "icons/file.gif").createImage(); + public final static Image BINARY = JcrUiPlugin.getImageDescriptor( + "icons/binary.png").createImage(); + public final static Image HOME = JcrUiPlugin.getImageDescriptor( + "icons/home.gif").createImage(); + +} diff --git a/gis/plugins/org.argeo.gis.ui.rcp.swing/src/main/java/org/argeo/gis/ui/rcp/swing/SwingMapViewer.java b/gis/plugins/org.argeo.gis.ui.rcp.swing/src/main/java/org/argeo/gis/ui/rcp/swing/SwingMapViewer.java index 6a1ed0fc1..dd272b45a 100644 --- a/gis/plugins/org.argeo.gis.ui.rcp.swing/src/main/java/org/argeo/gis/ui/rcp/swing/SwingMapViewer.java +++ b/gis/plugins/org.argeo.gis.ui.rcp.swing/src/main/java/org/argeo/gis/ui/rcp/swing/SwingMapViewer.java @@ -1,5 +1,6 @@ package org.argeo.gis.ui.rcp.swing; +import java.awt.Color; import java.awt.Frame; import javax.jcr.Node; @@ -31,6 +32,7 @@ public class SwingMapViewer extends AbstractMapViewer { mapPane = new JMapPane(new StreamingRenderer(), new DefaultMapContext()); versatileZoomTool = new VersatileZoomTool(); mapPane.setCursorTool(versatileZoomTool); + mapPane.setBackground(Color.WHITE); frame.add(mapPane); @@ -42,6 +44,7 @@ public class SwingMapViewer extends AbstractMapViewer { FeatureSource featureSource) { // TODO: deal with style and rasters mapPane.getMapContext().addLayer(featureSource, null); + mapPane.reset(); } } 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 bf949b01c..94768c374 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 @@ -6,6 +6,7 @@ import org.argeo.gis.ui.MapControlCreator; import org.argeo.gis.ui.MapViewer; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorInput; @@ -42,6 +43,8 @@ public class DefaultMapEditor extends EditorPart { layout.marginWidth = 0; mapArea.setLayout(layout); mapViewer = mapControlCreator.createMapControl(context, mapArea); + mapViewer.getControl().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); } public MapViewer getMapViewer() { 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 index 5c454d2c9..e6b5984f7 100644 --- 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 @@ -9,6 +9,7 @@ import org.argeo.gis.ui.MapViewer; import org.argeo.gis.ui.MapViewerListener; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.forms.AbstractFormPart; @@ -45,6 +46,8 @@ public class MapFormPage extends FormPage { layout.marginWidth = 0; mapArea.setLayout(layout); mapViewer = mapControlCreator.createMapControl(context, mapArea); + mapViewer.getControl().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); // form part MapFormPart mapFormPart = new MapFormPart(); 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 7d78bffc8..b13daaf83 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 @@ -5,16 +5,19 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.jcr.JcrImages; import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider; 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.ColumnLabelProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.forms.editor.FormEditor; @@ -85,12 +88,37 @@ public class FeatureSourcesView extends ViewPart implements this.session = session; } - private class MapsLabelProvider extends LabelProvider { + private class MapsLabelProvider extends ColumnLabelProvider { @Override public String getText(Object element) { + try { + if (element instanceof Node) { + Node node = (Node) element; + return node.getName(); + } + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get text", e); + } return super.getText(element); } + @Override + public Image getImage(Object element) { + try { + if (element instanceof Node) { + Node node = (Node) element; + if (node.isNodeType(GisTypes.GIS_FEATURE_SOURCE)) + return JcrImages.BINARY; + else if (node.isNodeType(GisTypes.GIS_DATA_STORE)) + return JcrImages.NODE; + return JcrImages.FOLDER; + } + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get text", e); + } + return super.getImage(element); + } + } } diff --git a/gis/runtime/org.argeo.gis.geotools/pom.xml b/gis/runtime/org.argeo.gis.geotools/pom.xml index d25330690..f22db4dcb 100644 --- a/gis/runtime/org.argeo.gis.geotools/pom.xml +++ b/gis/runtime/org.argeo.gis.geotools/pom.xml @@ -29,7 +29,7 @@ ${version.maven-bundle-plugin} - org.argeo.geotools.* + org.argeo.geotools.*,org.argeo.jts.* org.argeo.jcr.gis,* @@ -134,6 +134,12 @@ + + + org.eclipse.osgi + org.eclipse.osgi + + org.argeo.commons.osgi diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsConstants.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsConstants.java index 060b80385..7538f2faf 100644 --- a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsConstants.java +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/GeoToolsConstants.java @@ -1,6 +1,12 @@ package org.argeo.geotools; +import org.geotools.data.DataStore; + +/** Constants used by the GeoTools utilities. */ public interface GeoToolsConstants { + /** + * Property used to bastract the identification of some objects (typically + * {@link DataStore}. Especially useful as service property in OSGi. + */ public final static String ALIAS_KEY = "alias"; - public final static String PUBLISHED_FEATURE_SOURCES_KEY = "publishedFeatureSources"; } 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 b384eb3b6..7e4f28702 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 @@ -62,12 +62,16 @@ public class GeoJcrIndex implements EventListener, GisNames, GisTypes { // TODO: use common factory finder? private FilterFactory2 ff = new FilterFactoryImpl(); + /** Expects to execute with system authentication */ public void init() { - systemExecutionService.execute(new Runnable() { - public void run() { - initGeoJcrIndex(); - } - }); + if (systemExecutionService != null)// legacy + systemExecutionService.execute(new Runnable() { + public void run() { + initGeoJcrIndex(); + } + }); + else + initGeoJcrIndex(); } protected void initGeoJcrIndex() { @@ -291,8 +295,7 @@ public class GeoJcrIndex implements EventListener, GisNames, GisTypes { this.session = session; } - public void setSystemExecutionService( - Executor systemExecutionService) { + public void setSystemExecutionService(Executor systemExecutionService) { this.systemExecutionService = systemExecutionService; } 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 0619e5215..f7ac0df8a 100644 --- a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/jcr/SimpleGeoJcrMapper.java @@ -18,6 +18,7 @@ import org.argeo.ArgeoException; import org.argeo.geotools.GeoToolsConstants; import org.argeo.geotools.GeoToolsUtils; import org.argeo.jcr.JcrUtils; +import org.argeo.jcr.gis.GisJcrConstants; import org.argeo.jcr.gis.GisNames; import org.argeo.jcr.gis.GisTypes; import org.argeo.jts.jcr.JtsJcrUtils; @@ -35,14 +36,22 @@ import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; -public class SimpleGeoJcrMapper implements GeoJcrMapper { +public class SimpleGeoJcrMapper implements GeoJcrMapper, GisNames { private final static Log log = LogFactory.getLog(SimpleGeoJcrMapper.class); - private String dataStoresBasePath = "/gis/dataStores"; - private Map registeredDataStores = Collections .synchronizedSortedMap(new TreeMap()); + private Session systemSession; + + public void init() throws RepositoryException { + } + + public void dispose() { + if (systemSession != null) + systemSession.logout(); + } + public Map>> getPossibleFeatureSources() { Map>> res = new TreeMap>>(); dataStores: for (String alias : registeredDataStores.keySet()) { @@ -121,7 +130,7 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { log.warn("Cannot lookup EPSG code", e); srs = crs.toWKT(); } - featureNode.setProperty(GisNames.GIS_SRS, srs); + featureNode.setProperty(GIS_SRS, srs); Polygon bboxPolygon; Geometry envelope = geometry.getEnvelope(); @@ -142,10 +151,10 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { } bbox = JtsJcrUtils.writeWkb(featureNode.getSession(), bboxPolygon); - featureNode.setProperty(GisNames.GIS_BBOX, bbox); + featureNode.setProperty(GIS_BBOX, bbox); centroid = JtsJcrUtils.writeWkb(featureNode.getSession(), geometry.getCentroid()); - featureNode.setProperty(GisNames.GIS_CENTROID, centroid); + featureNode.setProperty(GIS_CENTROID, centroid); featureSourceNode.getSession().save(); return featureNode; } else { @@ -160,25 +169,21 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { } } - protected Node getNode(Session session, String dataStoreAlias) { + protected Node getDataStoreNode(Session session, String dataStoreAlias) { try { - Node dataStores; - if (!session.itemExists(dataStoresBasePath)) { - dataStores = JcrUtils.mkdirs(session, dataStoresBasePath); - dataStores.getSession().save(); - } else - dataStores = session.getNode(dataStoresBasePath); - - Node dataStoreNode; - if (dataStores.hasNode(dataStoreAlias)) - dataStoreNode = dataStores.getNode(dataStoreAlias); - else { - dataStoreNode = dataStores.addNode(dataStoreAlias, - GisTypes.GIS_DATA_STORE); - dataStoreNode.getSession().save(); - } + // normalize by starting with a '/' + String path = dataStoreAlias.startsWith("/") ? GisJcrConstants.DATA_STORES_BASE_PATH + + dataStoreAlias + : GisJcrConstants.DATA_STORES_BASE_PATH + '/' + + dataStoreAlias; + Node dataStoreNode = JcrUtils.mkdirs(session, path, + GisTypes.GIS_DATA_STORE); + dataStoreNode.setProperty(GIS_ALIAS, dataStoreAlias); + if (session.hasPendingChanges()) + session.save(); return dataStoreNode; } catch (RepositoryException e) { + JcrUtils.discardQuietly(session); throw new ArgeoException("Cannot get node for data store " + dataStoreAlias, e); } @@ -187,12 +192,14 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { public Node getFeatureSourceNode(Session session, String dataStoreAlias, FeatureSource featureSource) { try { - String name = featureSource.getName().toString(); - Node dataStoreNode = getNode(session, dataStoreAlias); - if (dataStoreNode.hasNode(name)) - return dataStoreNode.getNode(name); + // String name = featureSource.getName().toString(); + Name name = featureSource.getName(); + String nodeName = name.getLocalPart(); + Node dataStoreNode = getDataStoreNode(session, dataStoreAlias); + if (dataStoreNode.hasNode(nodeName)) + return dataStoreNode.getNode(nodeName); else { - Node featureSourceNode = dataStoreNode.addNode(name); + Node featureSourceNode = dataStoreNode.addNode(nodeName); featureSourceNode.addMixin(GisTypes.GIS_FEATURE_SOURCE); featureSourceNode.getSession().save(); return featureSourceNode; @@ -210,11 +217,14 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { try { Node dataStoreNode = node.getParent(); // TODO: check a dataStore type - if (!registeredDataStores.containsKey(dataStoreNode.getName())) + if (!dataStoreNode.hasProperty(GIS_ALIAS)) + throw new ArgeoException("Data store " + dataStoreNode + + " is not active."); + String alias = dataStoreNode.getProperty(GIS_ALIAS).getString(); + if (!registeredDataStores.containsKey(alias)) throw new ArgeoException("No data store registered under " + dataStoreNode); - DataStore dataStore = registeredDataStores.get(dataStoreNode - .getName()); + DataStore dataStore = registeredDataStores.get(alias); return dataStore.getFeatureSource(node.getName()); } catch (Exception e) { throw new ArgeoException("Cannot find feature source " + node, e); @@ -226,25 +236,63 @@ public class SimpleGeoJcrMapper implements GeoJcrMapper { return null; } - public void register(DataStore dataStore, Map properties) { + public synchronized void register(DataStore dataStore, + Map properties) { if (!properties.containsKey(GeoToolsConstants.ALIAS_KEY)) { log.warn("Cannot register data store " + dataStore + " since it has no '" + GeoToolsConstants.ALIAS_KEY + "' property"); return; } - registeredDataStores.put(properties.get(GeoToolsConstants.ALIAS_KEY), - dataStore); + String alias = properties.get(GeoToolsConstants.ALIAS_KEY); + Node dataStoreNode = getDataStoreNode(systemSession, alias); + try { + dataStoreNode.setProperty(GIS_ALIAS, alias); + + // TODO synchronize namespace if registered + for (Name name : dataStore.getNames()) { + String sourceName = name.getLocalPart(); + if (!dataStoreNode.hasNode(sourceName)) { + Node featureSourceNode = dataStoreNode.addNode(sourceName); + featureSourceNode.addMixin(GisTypes.GIS_FEATURE_SOURCE); + } + } + + // TODO check feature sources which are registered but not available + // anymore + systemSession.save(); + registeredDataStores.put(alias, dataStore); + JcrUtils.discardQuietly(systemSession); + } catch (Exception e) { + throw new ArgeoException("Cannot register data store " + alias + + ", " + dataStore, e); + } } - public void unregister(DataStore dataStore, Map properties) { + public synchronized void unregister(DataStore dataStore, + Map properties) { if (!properties.containsKey(GeoToolsConstants.ALIAS_KEY)) { log.warn("Cannot unregister data store " + dataStore + " since it has no '" + GeoToolsConstants.ALIAS_KEY + "' property"); return; } - registeredDataStores - .remove(properties.get(GeoToolsConstants.ALIAS_KEY)); + String alias = properties.get(GeoToolsConstants.ALIAS_KEY); + registeredDataStores.remove(alias); + Node dataStoreNode = getDataStoreNode(systemSession, alias); + try { + dataStoreNode.getProperty(GIS_ALIAS).remove(); + systemSession.save(); + } catch (RepositoryException e) { + JcrUtils.discardQuietly(systemSession); + throw new ArgeoException("Cannot unregister data store " + alias + + ", " + dataStore, e); + } } + + /** Expects to own this session (will be logged out on dispose) */ + public void setSystemSession(Session systemSession) { + this.systemSession = systemSession; + } + } diff --git a/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/osgi/GisResourcesActivator.java b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/osgi/GisResourcesActivator.java new file mode 100644 index 000000000..e904df7e8 --- /dev/null +++ b/gis/runtime/org.argeo.gis.geotools/src/main/java/org/argeo/geotools/osgi/GisResourcesActivator.java @@ -0,0 +1,67 @@ +package org.argeo.geotools.osgi; + +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.geotools.GeoToolsConstants; +import org.geotools.data.DataStore; +import org.geotools.data.FileDataStoreFinder; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * Publishes as OSGi services (typically {@link DataStore}) resources contained + * or references within the bundle declaring this activator. + */ +public class GisResourcesActivator implements BundleActivator { + private final static Log log = LogFactory + .getLog(GisResourcesActivator.class); + + /** + * Keep track of the registered datastores in order to dispose them when the + * bundle is stopped. + */ + private Map registeredDataStores = new HashMap(); + + @SuppressWarnings("unchecked") + public void start(BundleContext context) throws Exception { + Bundle bundle = context.getBundle(); + + // TODO deal with other data types + // shapefiles + Enumeration resources = bundle.findEntries("/", "*.shp", true); + while (resources.hasMoreElements()) { + URL url = resources.nextElement(); + DataStore ds = FileDataStoreFinder.getDataStore(url); + Properties props = new Properties(); + String alias = url.getPath(); + props.setProperty(GeoToolsConstants.ALIAS_KEY, alias); + context.registerService(DataStore.class.getName(), ds, props); + registeredDataStores.put(alias, ds); + if (log.isDebugEnabled()) + log.debug("Registered data store " + alias + ": " + ds); + } + } + + public void stop(BundleContext context) throws Exception { + for (String alias : registeredDataStores.keySet()) { + DataStore ds = registeredDataStores.get(alias); + try { + ds.dispose(); + if (log.isDebugEnabled()) + log.debug("Disposed data store " + alias + ": " + ds); + } catch (Exception e) { + log.warn("Could not dispose data store " + ds + ": " + + e.getMessage()); + } + } + + } + +} diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java index 0ad12327f..3dab19312 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java @@ -89,7 +89,24 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, private Executor systemExecutor; private Credentials adminCredentials; + // transition from legacy spring approach + private Boolean alreadyInitialized = false; + private Boolean alreadyDisposed = false; + + /** @deprecated explicitly declare {@link #init()} as init-method instead. */ public void afterPropertiesSet() throws Exception { + log.warn("## This initialization approach is deprecated and will be removed," + + " declare init-method=\"init\" instead."); + if (!alreadyInitialized) + initImpl(); + } + + public void init() throws Exception { + initImpl(); + alreadyInitialized = true; + } + + protected void initImpl() throws Exception { if (repository != null) { // we are just wrapping another repository importNodeTypeDefinitions(repository); @@ -143,6 +160,47 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, + homeDirectory + " with config " + configuration); } + /** + * @deprecated explicitly declare {@link #dispose()} as destroy-method + * instead. + */ + public void destroy() throws Exception { + log.warn("## This dispose approach is deprecated and will be removed," + + " declare destroy-method=\"dispose\" instead."); + if (!alreadyDisposed) + disposeImpl(); + } + + public void dispose() throws Exception { + disposeImpl(); + alreadyDisposed = true; + } + + protected void disposeImpl() throws Exception { + if (repository != null) { + if (repository instanceof JackrabbitRepository) + ((JackrabbitRepository) repository).shutdown(); + else if (repository instanceof RepositoryImpl) + ((RepositoryImpl) repository).shutdown(); + else if (repository instanceof TransientRepository) + ((TransientRepository) repository).shutdown(); + } + + if (inMemory) + if (homeDirectory.exists()) { + FileUtils.deleteDirectory(homeDirectory); + if (log.isDebugEnabled()) + log.debug("Deleted Jackrabbit home directory " + + homeDirectory); + } + + if (uri != null && !uri.trim().equals("")) + log.info("Destroyed Jackrabbit repository with uri " + uri); + else + log.info("Destroyed Jackrabbit repository " + repository + " in " + + homeDirectory + " with config " + configuration); + } + protected Properties getConfigurationProperties() { InputStream propsIn = null; Properties vars; @@ -221,31 +279,6 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean, action.run(); } - public void destroy() throws Exception { - if (repository != null) { - if (repository instanceof JackrabbitRepository) - ((JackrabbitRepository) repository).shutdown(); - else if (repository instanceof RepositoryImpl) - ((RepositoryImpl) repository).shutdown(); - else if (repository instanceof TransientRepository) - ((TransientRepository) repository).shutdown(); - } - - if (inMemory) - if (homeDirectory.exists()) { - FileUtils.deleteDirectory(homeDirectory); - if (log.isDebugEnabled()) - log.debug("Deleted Jackrabbit home directory " - + homeDirectory); - } - - if (uri != null && !uri.trim().equals("")) - log.info("Destroyed Jackrabbit repository with uri " + uri); - else - log.info("Destroyed Jackrabbit repository " + repository + " in " - + homeDirectory + " with config " + configuration); - } - // JCR REPOSITORY (delegated) public String getDescriptor(String key) { return repository.getDescriptor(key); diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisJcrConstants.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisJcrConstants.java new file mode 100644 index 000000000..bc55174b7 --- /dev/null +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisJcrConstants.java @@ -0,0 +1,8 @@ +package org.argeo.jcr.gis; + +/** Constants related to GIS in JCR, typically standard paths. */ +public class GisJcrConstants { + + public final static String DATA_STORES_BASE_PATH = "/gis/dataStores"; + +} diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java index e8eca58cf..3bc6db0d3 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/gis/GisNames.java @@ -5,6 +5,8 @@ public interface GisNames { public final static String GIS_NAMESPACE = "http://www.argeo.org/ns/gis"; public final static String GIS_ = "gis:"; + public final static String GIS_ALIAS = "gis:alias"; + public final static String GIS_SRS = "gis:srs"; public final static String GIS_BBOX = "gis:bbox"; public final static String GIS_CENTROID = "gis:centroid"; -- 2.30.2