package com.revolsys.swing.map.layer.mapguide; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Consumer; import com.revolsys.beans.Classes; import com.revolsys.collection.map.MapEx; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.io.PathName; import com.revolsys.io.map.MapObjectFactoryRegistry; import com.revolsys.logging.Logs; import com.revolsys.record.Record; import com.revolsys.record.io.RecordReader; import com.revolsys.record.io.format.esri.rest.ArcGisRestCatalog; import com.revolsys.record.io.format.mapguide.FeatureLayer; import com.revolsys.record.query.Query; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.spring.resource.UrlResource; import com.revolsys.swing.map.layer.AbstractLayer; import com.revolsys.swing.map.layer.LayerGroup; import com.revolsys.swing.map.layer.Project; import com.revolsys.swing.map.layer.arcgisrest.ArcGisRestServerRecordLayer; import com.revolsys.swing.map.layer.record.AbstractRecordLayer; import com.revolsys.swing.map.layer.record.LayerRecord; import com.revolsys.swing.menu.MenuFactory; import com.revolsys.swing.menu.Menus; import com.revolsys.util.OS; import com.revolsys.util.PasswordUtil; import com.revolsys.util.Property; public class MapGuideWebServerRecordLayer extends AbstractRecordLayer { private static final String J_TYPE = "mapGuideWebServerRecordLayer"; private static void actionAddLayer(final FeatureLayer layerDescription) { final Project project = Project.get(); if (project != null) { LayerGroup layerGroup = project; final PathName layerPath = layerDescription.getPathName(); for (final String groupName : layerPath.getParent().getElements()) { layerGroup = layerGroup.addLayerGroup(groupName); } final MapGuideWebServerRecordLayer layer = new MapGuideWebServerRecordLayer(layerDescription); layerGroup.addLayer(layer); if (OS.getPreferenceBoolean("com.revolsys.gis", AbstractLayer.PREFERENCE_PATH, AbstractLayer.PREFERENCE_NEW_LAYERS_SHOW_TABLE_VIEW, false)) { layer.showTableView(); } } } public static void mapObjectFactoryInit() { MapObjectFactoryRegistry.newFactory(J_TYPE, "Map Guide Web Server Record Layer", ArcGisRestServerRecordLayer::new); final MenuFactory recordLayerDescriptionMenu = MenuFactory.getMenu(FeatureLayer.class); Menus.addMenuItem(recordLayerDescriptionMenu, "default", "Add Layer", "map_add", MapGuideWebServerRecordLayer::actionAddLayer, false); } private FeatureLayer webServiceLayer; private String url; private PathName layerPath; private String password; private String username; public MapGuideWebServerRecordLayer() { super(J_TYPE); setReadOnly(true); } public MapGuideWebServerRecordLayer(final FeatureLayer layerDescription) { this(); setWebServiceLayer(layerDescription); setProperties(Collections.emptyMap()); } public MapGuideWebServerRecordLayer(final Map<String, ? extends Object> properties) { this(); setProperties(properties); } @Override protected void forEachRecordInternal(final Query query, final Consumer<? super LayerRecord> consumer) { try ( RecordReader reader = this.webServiceLayer.newRecordReader(this::newLayerRecord, query)) { for (final Record record : reader) { consumer.accept((LayerRecord)record); } } } public PathName getLayerPath() { return this.layerPath; } @Override public int getRecordCount(final Query query) { if (this.webServiceLayer == null) { return 0; } else { return this.webServiceLayer.getRecordCount(query); } } @Override public List<LayerRecord> getRecords(BoundingBox boundingBox) { if (hasGeometryField()) { boundingBox = convertBoundingBox(boundingBox); if (Property.hasValue(boundingBox)) { final List<LayerRecord> records = this.webServiceLayer.getRecords(this::newLayerRecord, boundingBox); return records; } } return Collections.emptyList(); } public String getUrl() { return this.url; } public FeatureLayer getWebServiceLayer() { return this.webServiceLayer; } @Override protected boolean initializeDo() { FeatureLayer webServiceLayer = getWebServiceLayer(); if (webServiceLayer == null) { final String url = getUrl(); final PathName layerPath = getLayerPath(); if (url == null) { Logs.error(this, Classes.className(this) + " requires a url: " + getPath()); return false; } if (layerPath == null) { Logs.error(this, Classes.className(this) + " requires a layerPath: " + getPath()); return false; } ArcGisRestCatalog server; try { server = ArcGisRestCatalog.newArcGisRestCatalog(url); } catch (final Throwable e) { Logs.error(this, "Unable to connect to server: " + url + " for " + getPath(), e); return false; } try { webServiceLayer = server.getWebServiceResource(layerPath, FeatureLayer.class); } catch (final IllegalArgumentException e) { Logs.error(this, "Layer is not valid: " + getPath(), e); return false; } if (webServiceLayer == null) { Logs.error(this, "Layer does not exist: " + layerPath + " for " + getPath()); return false; } else { setWebServiceLayer(webServiceLayer); } } if (webServiceLayer != null) { final RecordDefinition recordDefinition = webServiceLayer.getRecordDefinition(); if (recordDefinition != null) { setRecordDefinition(recordDefinition); setBoundingBox(webServiceLayer.getBoundingBox()); // initRenderer(); return super.initializeDo(); } } return false; } public void setLayerPath(final PathName layerPath) { this.layerPath = layerPath; } public void setPassword(final String password) { this.password = PasswordUtil.decrypt(password); } public void setUrl(final String url) { this.url = url; } public void setUrl(final UrlResource url) { if (url != null) { setUrl(url.getUriString()); this.username = url.getUsername(); this.password = url.getPassword(); } } public void setUsername(final String username) { this.username = username; } public void setWebServiceLayer(final FeatureLayer layerDescription) { this.webServiceLayer = layerDescription; if (this.webServiceLayer != null) { final String name = this.webServiceLayer.getName(); setName(name); final UrlResource serviceUrl = this.webServiceLayer.getWebService().getServiceUrl(); setUrl(serviceUrl); final PathName pathName = this.webServiceLayer.getPathName(); setLayerPath(pathName); } } @Override public MapEx toMap() { final MapEx map = super.toMap(); addToMap(map, "url", this.url); addToMap(map, "username", this.username); addToMap(map, "password", PasswordUtil.encrypt(this.password)); addToMap(map, "layerPath", this.layerPath); return map; } }