package com.revolsys.record.io.format.mapguide; import java.io.InputStream; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import com.revolsys.collection.map.LinkedHashMapEx; import com.revolsys.collection.map.MapEx; import com.revolsys.collection.map.Maps; import com.revolsys.io.PathName; import com.revolsys.io.map.MapObjectFactoryRegistry; import com.revolsys.logging.Logs; import com.revolsys.record.io.format.json.Json; import com.revolsys.spring.resource.Resource; import com.revolsys.spring.resource.UrlResource; import com.revolsys.util.Property; import com.revolsys.webservice.AbstractWebService; import com.revolsys.webservice.WebServiceResource; public class MapGuideWebService extends AbstractWebService<MapGuideResource> { public static final String J_TYPE = "mapGuideWebServer"; private static final Map<String, Function<MapEx, ResourceDocument>> RESOURCE_DOCUMENT_FACTORIES = Maps .<String, Function<MapEx, ResourceDocument>> buildHash() // .add("ApplicationDefinition", ApplicationDefinition::new) .add("DrawingSource", DrawingSource::new) .add("FeatureSource", FeatureSource::new) .add("LayerDefinition", LayerDefinition::new) .add("LoadProcedure", LoadProcedure::new) .add("MapDefinition", MapDefinition::new) .add("SymbolDefinition", SymbolDefinition::new) .add("SymbolLibrary", SymbolLibrary::new) .add("WatermarkDefinition", WatermarkDefinition::new) .getMap(); public static void mapObjectFactoryInit() { MapObjectFactoryRegistry.newFactory(J_TYPE, "Map Guide Web Server", MapGuideWebService::newMapGuideWebService); } public static MapGuideWebService newMapGuideWebService( final Map<String, ? extends Object> properties) { final String serviceUrl = (String)properties.get("serviceUrl"); if (Property.hasValue(serviceUrl)) { final MapGuideWebService service = new MapGuideWebService(serviceUrl); // service.setProperties(properties); return service; } else { throw new IllegalArgumentException("Missing serviceUrl"); } } private final Object resfreshSync = new Object(); private boolean initialized = false; private Folder root; public MapGuideWebService(final String serviceUrl) { super(serviceUrl); } @Override public <R extends WebServiceResource> R getChild(final String name) { refreshIfNeeded(); if (this.root == null) { return null; } else { return this.root.getChild(name); } } @Override public List<MapGuideResource> getChildren() { refreshIfNeeded(); if (this.root == null) { return Collections.emptyList(); } else { return this.root.getChildren(); } } @Override public String getIconName() { return "folder:world"; } public InputStream getInputStream(final String operation, final String format, final Map<String, ? extends Object> parameters) { final Resource resource = getResource(operation, format, parameters); return resource.getInputStream(); } public MapEx getJsonResponse(final String operation, final Map<String, ? extends Object> parameters) { final Resource resource = getResource(operation, "application/json", parameters); return Json.toMap(resource); } public Resource getResource(final String operation, final String format, final Map<String, ? extends Object> parameters) throws Error { final MapEx newParameters = new LinkedHashMapEx(parameters); newParameters.put("VERSION", "1.0.0"); newParameters.put("OPERATION", operation); newParameters.put("format", format); final UrlResource serviceUrl = getServiceUrl(); final UrlResource mapAgentUrl = serviceUrl.newChildResource("mapagent/mapagent.fcgi"); final UrlResource resource = mapAgentUrl.newUrlResource(newParameters); return resource; } public Map<PathName, MapGuideResource> getResources(final String path) { final MapEx parameters = new LinkedHashMapEx(); parameters.put("RESOURCEID", "Library:/" + path); parameters.put("COMPUTECHILDREN", "1"); parameters.put("DEPTH", "-1"); final MapEx response = getJsonResponse("ENUMERATERESOURCES", parameters); final MapEx resourceList = response.getValue("ResourceList"); final List<MapEx> resourceFolders = resourceList.getValue("ResourceFolder"); final Map<PathName, Folder> folderByPath = new HashMap<>(); final Map<PathName, MapGuideResource> resourceByPath = new HashMap<>(); for (final MapEx resourceDefinition : resourceFolders) { final Folder folder = new Folder(resourceDefinition); folder.setWebService(this); final PathName resourcePath = folder.getPath(); folderByPath.put(resourcePath, folder); resourceByPath.put(resourcePath, folder); final PathName parentPath = resourcePath.getParent(); if (parentPath != null) { final Folder parent = folderByPath.get(parentPath); parent.addResource(folder); } } final List<MapEx> resourceDocuments = resourceList.getValue("ResourceDocument"); for (final MapEx resourceDefinition : resourceDocuments) { final List<String> resourceIdList = resourceDefinition.getValue("ResourceId"); final String resourceId = resourceIdList.get(0); final String resourceType = resourceId.substring(resourceId.lastIndexOf(".") + 1); final Function<MapEx, ResourceDocument> factory = RESOURCE_DOCUMENT_FACTORIES .get(resourceType); if (factory != null) { final ResourceDocument resource = factory.apply(resourceDefinition); resource.setWebService(this); final PathName resourcePath = resource.getPath(); resourceByPath.put(resourcePath, resource); final PathName parentPath = resourcePath.getParent(); if (parentPath != null) { final Folder parent = folderByPath.get(parentPath); parent.addResource(resource); } } else { Logs.debug(this, "Unsupported resource type: " + resourceType); } } final Folder root = folderByPath.get(PathName.ROOT); if (root != null) { this.root = root; } return resourceByPath; } @Override public String getWebServiceTypeName() { return J_TYPE; } @Override public final void refresh() { synchronized (this.resfreshSync) { refreshDo(); } } protected void refreshDo() { getResources("/"); } public final void refreshIfNeeded() { synchronized (this.resfreshSync) { if (!this.initialized) { this.initialized = true; refresh(); } } } }