From 5cc0de0482d562159f04fec3f9a65cf98d37f015 Mon Sep 17 00:00:00 2001 From: haileyajohnson Date: Mon, 4 Jun 2018 16:41:58 -0600 Subject: [PATCH 1/5] add base template for catalog and catalog service reformat context which gets passed to the thymleaf template --- .../CatalogServiceController.java | 119 ++++++---- .../CatalogViewContextParser.java | 224 ++++++++++++++++++ .../RemoteCatalogServiceController.java | 8 +- .../webapp/WEB-INF/templates/catalog.html | 33 +++ .../WEB-INF/templates/catalogService.html | 48 ++++ .../WEB-INF/templates/commonFragments.html | 18 +- .../WEB-INF/templates/gridFragments.html | 15 +- 7 files changed, 392 insertions(+), 73 deletions(-) create mode 100644 tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java create mode 100644 tds/src/main/webapp/WEB-INF/templates/catalog.html create mode 100644 tds/src/main/webapp/WEB-INF/templates/catalogService.html diff --git a/tds/src/main/java/thredds/server/catalogservice/CatalogServiceController.java b/tds/src/main/java/thredds/server/catalogservice/CatalogServiceController.java index 9f43b27d77..698f957698 100644 --- a/tds/src/main/java/thredds/server/catalogservice/CatalogServiceController.java +++ b/tds/src/main/java/thredds/server/catalogservice/CatalogServiceController.java @@ -22,6 +22,7 @@ import java.io.FileNotFoundException; import java.net.URI; import java.net.URISyntaxException; +import java.util.*; /** * LocalCatalogServiceController using client/server catalogs @@ -33,64 +34,78 @@ @Controller @RequestMapping(value = "/catalog") public class CatalogServiceController { - // private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(getClass()); - - @Autowired - private CatalogManager catalogManager; - - @Autowired - ConfigCatalogHtmlWriter writer; - - @RequestMapping(value = "**", method = {RequestMethod.GET}) - protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response, CatalogRequest params) throws Exception { + // private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(getClass()); + + @Autowired + private CatalogManager catalogManager; + + @Autowired + ConfigCatalogHtmlWriter writer; + + @RequestMapping(value = "**", method = {RequestMethod.GET}) + protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response, CatalogRequest params) throws Exception { + + TdsRequestedDataset reqD = new TdsRequestedDataset(request, "/catalog"); + String path = reqD.getPath(); + boolean isHtml = path.endsWith(".html"); + String catalogPath = path.replaceAll(".html$", ".xml"); + + Catalog catalog; + URI baseUri; + String baseUriString = request.getRequestURL().toString(); + try { + baseUri = new URI(baseUriString); + catalog = catalogManager.getCatalog(catalogPath, baseUri); + + } catch (URISyntaxException e) { + String msg = "Bad URI syntax [" + baseUriString + "]: " + e.getMessage(); + throw new URISyntaxException(msg, e.getReason()); + } + + // no catalog found + if (catalog == null) + throw new FileNotFoundException(request.getRequestURI()); + + if (isHtml) { + return handleHTMLRequest(request, response, catalog, params); + } else { + return handleXMLRequest(request, response, catalog, params); + } + } - TdsRequestedDataset reqD = new TdsRequestedDataset(request, "/catalog"); - String path = reqD.getPath(); - boolean isHtml = path.endsWith(".html"); - String catalogPath = path.replaceAll(".html$", ".xml"); + protected ModelAndView handleXMLRequest(HttpServletRequest request, HttpServletResponse response, Catalog catalog, CatalogRequest params) throws Exception { + if (params.dataset != null) { + Dataset dataset = catalog.findDatasetByID(params.dataset); + if (dataset == null) + throw new FileNotFoundException("Did not find dataset [" + params.dataset + "] in catalog [" + request.getRequestURL().toString() + "]."); - Catalog catalog; - URI baseUri; - String baseUriString = request.getRequestURL().toString(); - try { - baseUri = new URI(baseUriString); - catalog = catalogManager.getCatalog(catalogPath, baseUri); + Catalog subsetCat = catalog.subsetCatalogOnDataset(dataset); + return new ModelAndView("threddsInvCatXmlView", "catalog", subsetCat); - } catch (URISyntaxException e) { - String msg = "Bad URI syntax [" + baseUriString + "]: " + e.getMessage(); - throw new URISyntaxException(msg, e.getReason()); + } else { + return new ModelAndView("threddsInvCatXmlView", "catalog", catalog); + } } - // no catalog found - if (catalog == null) - throw new FileNotFoundException(request.getRequestURI()); - - // Otherwise, handle catalog as indicated by "command". - if (params.dataset != null) { - Dataset dataset = catalog.findDatasetByID(params.dataset); - if (dataset == null) - throw new FileNotFoundException("Did not find dataset [" + params.dataset + "] in catalog [" + baseUriString + "]."); - - if (isHtml) { - int i = writer.showDataset(baseUriString, dataset, request, response, true); - return null; - - } else { - Catalog subsetCat = catalog.subsetCatalogOnDataset(dataset); - return new ModelAndView("threddsInvCatXmlView", "catalog", subsetCat); - } - - } else { - if (isHtml) { - int i = writer.writeCatalog(request, response, catalog, true); - return null; - - } else { - return new ModelAndView("threddsInvCatXmlView", "catalog", catalog); - } + protected ModelAndView handleHTMLRequest(HttpServletRequest request, HttpServletResponse response, Catalog catalog, CatalogRequest params) throws Exception { + if (params.dataset != null) { + Dataset dataset = catalog.findDatasetByID(params.dataset); + if (dataset == null) + throw new FileNotFoundException("Did not find dataset [" + params.dataset + "] in catalog [" + request.getRequestURL().toString() + "]."); + + Catalog subsetCat = catalog.subsetCatalogOnDataset(dataset); + + int i = writer.showDataset(request.getRequestURL().toString(), dataset, request, response, true); + return null; +// Map model = new HashMap<>(); +// model.put("catalog", subsetCat); +// return new ModelAndView("templates/dataset", CatalogViewContextParser.getDatasetViewContext(dataset, true)); + } else { +// int i = writer.writeCatalog(request, response, catalog, true); +// return null; + return new ModelAndView("templates/catalog", CatalogViewContextParser.getCatalogViewContext(catalog, true)); + } } - } - /* private ModelAndView handlePublicDocumentRequest(HttpServletRequest request, HttpServletResponse response, String path) throws IOException, ServletException { diff --git a/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java b/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java new file mode 100644 index 0000000000..4f9b5cf4ad --- /dev/null +++ b/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java @@ -0,0 +1,224 @@ +package thredds.server.catalogservice; + +import org.springframework.beans.factory.annotation.Autowired; +import thredds.client.catalog.*; +import thredds.server.catalog.CatalogScan; +import thredds.server.catalog.DatasetScan; +import thredds.server.catalog.FeatureCollectionRef; +import thredds.server.config.HtmlConfigBean; +import thredds.server.config.TdsContext; +import ucar.nc2.units.DateType; +import ucar.unidata.util.Format; +import ucar.unidata.util.StringUtil2; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.*; + + +public class CatalogViewContextParser { + + public static Map getCatalogViewContext(Catalog cat, boolean isLocalCatalog) { + Map model = new HashMap<>(); + + // parse basic catalog contect + String uri = cat.getUriString(); + if (uri == null) uri = cat.getName(); + if (uri == null) uri = "unknown"; + model.put("uri", uri); + model.put("name", cat.getName()); + + List catalogItems = new ArrayList<>(); + for (Dataset ds : cat.getDatasets()) { + catalogItems.add(new CatalogItemContext(ds, 0, true)); + } + model.put("items", catalogItems); + return model; + } + + public static Map getDatasetViewContext(Dataset ds, boolean isLocalCatalog) + { + Map model = new HashMap<>(); + + return model; + } +} + +class CatalogItemContext { + + static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CatalogItemContext.class); + + @Autowired + private HtmlConfigBean htmlConfig; + + @Autowired + private TdsContext tdsContext; + + String displayName; + String iconSrc; + int level; + String dataSize; + String lastModified; + String itemhref; + boolean usehref = true; + List items; + + public CatalogItemContext(Dataset ds, int level, boolean isLocalCatalog) + { + // Get display name + this.displayName = ds.getName(); + + // Store nesting level + this.level = level; + + // Get href + if (ds instanceof CatalogRef) { + CatalogRef catref = (CatalogRef) ds; + String href = catref.getXlinkHref(); + if (!isLocalCatalog) { + URI hrefUri = ds.getParentCatalog().getBaseURI().resolve(href); + href = hrefUri.toString(); + } + try { + URI uri = new URI(href); + if (uri.isAbsolute()) { + boolean defaultUseRemoteCatalogService = htmlConfig.getUseRemoteCatalogService(); // read default as set in threddsConfig.xml + Boolean dsUseRemoteCatalogSerivce = ((CatalogRef) ds).useRemoteCatalogService(); // check to see if catalogRef contains tag that overrides default + boolean useRemoteCatalogService = defaultUseRemoteCatalogService; // by default, use the option found in threddsConfig.xml + if (dsUseRemoteCatalogSerivce == null) + dsUseRemoteCatalogSerivce = defaultUseRemoteCatalogService; // if the dataset does not have the useRemoteDataset option set, opt for the default behavior + + // if the default is not the same as what is defined in the catalog, go with the catalog option + // as the user has explicitly overridden the default + if (defaultUseRemoteCatalogService != dsUseRemoteCatalogSerivce) { + useRemoteCatalogService = dsUseRemoteCatalogSerivce; + } + + // now, do the right thing with using the remoteCatalogService, or not + if (useRemoteCatalogService) { + href = tdsContext.getContextPath() + "/remoteCatalogService?catalog=" + href; + } else { + int pos = href.lastIndexOf('.'); + href = href.substring(0, pos) + ".html"; + } + } else { + int pos = href.lastIndexOf('.'); + href = href.substring(0, pos) + ".html"; + } + + } catch (Exception e) {//(URISyntaxException e) { + log.error(href, e); + } + + this.itemhref = href; + + if (ds instanceof CatalogScan || ds.hasProperty("CatalogScan")) + this.iconSrc = "cat_folder.png"; + else if (ds instanceof DatasetScan || ds.hasProperty("DatasetScan")) + this.iconSrc = "scan_folder.png"; + else if (ds instanceof FeatureCollectionRef) + this.iconSrc = "fc_folder.png"; + else + this.iconSrc = "folder.png"; + + } else { // Not a CatalogRef + if (ds.hasNestedDatasets()) + this.iconSrc = "folder.png"; + + // Check if dataset has single resolver service. + if (ds.getAccess().size() == 1 && ServiceType.Resolver == ds.getAccess().get(0).getService().getType()) { + Access access = ds.getAccess().get(0); + String accessUrlName = access.getUnresolvedUrlName(); + int pos = accessUrlName.lastIndexOf(".xml"); + + if (accessUrlName.equalsIgnoreCase("latest.xml") && !isLocalCatalog) { + String catBaseUriPath = ""; + String catBaseUri = ds.getParentCatalog().getBaseURI().toString(); + pos = catBaseUri.lastIndexOf("catalog.xml"); + if (pos != -1) { + catBaseUriPath = catBaseUri.substring(0, pos); + } + accessUrlName = tdsContext.getContextPath() + "/remoteCatalogService?catalog=" + catBaseUriPath + accessUrlName; + } else if (pos != -1) { + accessUrlName = accessUrlName.substring(0, pos) + ".html"; + } + this.itemhref = accessUrlName; + + } else if (ds.findProperty(Dataset.NotAThreddsDataset) != null) { // Dataset can only be file served + // Write link to HTML dataset page. + this.itemhref = makeFileServerUrl(ds); + + } else if (ds.getID() != null) { // Dataset with an ID. //URI catURI = cat.getBaseURI(); + Catalog cat = ds.getParentCatalog(); + String catHtml; + if (!isLocalCatalog) { + // Setup HREF url to link to HTML dataset page (more below). + catHtml = tdsContext.getContextPath() + "/remoteCatalogService?command=subset&catalog=" + cat.getUriString() + "&"; + // Can't be "/catalogServices?..." because subset decides on xml or html by trailing ".html" on URL path + } else { // replace xml with html + URI catURI = cat.getBaseURI(); + // Get the catalog name - we want a relative URL + catHtml = catURI.getPath(); + if (catHtml == null) catHtml = cat.getUriString(); // if URI is a file + int pos = catHtml.lastIndexOf("/"); + if (pos != -1) catHtml = catHtml.substring(pos + 1); + // change the ending to "catalog.html?" + pos = catHtml.lastIndexOf('.'); + if (pos < 0) + catHtml = catHtml + "catalog.html?"; + else + catHtml = catHtml.substring(0, pos) + ".html?"; + } + + // Write link to HTML dataset page. + this.itemhref = catHtml + "dataset=" + StringUtil2.replace(ds.getID(), '+', "%2B"); + }else { + this.usehref = false; + } + } + + if (this.iconSrc != null) this.iconSrc = htmlConfig.prepareUrlStringForHtml(this.iconSrc); + + // Get data size + double size = ds.getDataSize(); + if ((size > 0) && !Double.isNaN(size)) + this.dataSize = (Format.formatByteSize(size)); + + + // Get last modified time. + DateType lastModDateType = ds.getLastModifiedDate(); + if (lastModDateType != null) + this.lastModified = lastModDateType.toDateTimeString(); + + if (!(ds instanceof CatalogRef)) { + + List catalogItems = new ArrayList<>(); + for (Dataset nestedItem : ds.getDatasets()) { + catalogItems.add(new CatalogItemContext(nestedItem, level+1, isLocalCatalog)); + } + } + } + + public String getDisplayName() { return this.displayName; } + + public String getIconSrc() { return this.iconSrc; } + + public int getLevel() { return this.level; } + + public String getDataSize() { return this.dataSize; } + + public String getLastModified() { return this.lastModified; } + + public String getHref() {return this.itemhref; } + + public boolean useHref() {return this.usehref; } + + public List getCatalogItems() { return this.items; } + + private String makeFileServerUrl(Dataset ds) { + Access acc = ds.getAccess(ServiceType.HTTPServer); + assert acc != null; + return acc.getStandardUrlName(); + } + +} diff --git a/tds/src/main/java/thredds/server/catalogservice/RemoteCatalogServiceController.java b/tds/src/main/java/thredds/server/catalogservice/RemoteCatalogServiceController.java index e7412897e7..5a254b9210 100644 --- a/tds/src/main/java/thredds/server/catalogservice/RemoteCatalogServiceController.java +++ b/tds/src/main/java/thredds/server/catalogservice/RemoteCatalogServiceController.java @@ -91,8 +91,7 @@ protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResp // Otherwise, handle catalog as indicated by "command". switch (params.getCommand()) { case SHOW: - writer.writeCatalog(request, response, catalog, false); - return null; + return new ModelAndView("templates/catalog", CatalogViewContextParser.getCatalogViewContext(catalog, false)); case SUBSET: String datasetId = params.getDataset(); @@ -105,9 +104,7 @@ protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResp } if (params.isHtmlView()) { - writer.showDataset(uri.toString(), dataset, request, response, false); - return null; - + return new ModelAndView("templates/Dataset", CatalogViewContextParser.getDatasetViewContext(dataset, false)); } else { Catalog subsetCat = catalog.subsetCatalogOnDataset(dataset); return new ModelAndView("threddsInvCatXmlView", "catalog", subsetCat); @@ -122,7 +119,6 @@ protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResp response.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); return null; } - } public static ModelAndView constructValidationMessageModelAndView(URI uri, String validationMessage, HtmlConfigBean htmlConfig) { diff --git a/tds/src/main/webapp/WEB-INF/templates/catalog.html b/tds/src/main/webapp/WEB-INF/templates/catalog.html new file mode 100644 index 0000000000..bd3ff6fc5b --- /dev/null +++ b/tds/src/main/webapp/WEB-INF/templates/catalog.html @@ -0,0 +1,33 @@ + + + + + Catalog + + + + +

Initial TDS Installation +

+
+ + + + + + + + + + + + +
DatasetSizeLast Modified
     + Folder   + +  --
+

Initial TDS Installation (please change threddsConfig.xml) at My Group see Info
+ THREDDS Data Server [Version $projectVersion - $buildTimestamp] Documentation

+ + \ No newline at end of file diff --git a/tds/src/main/webapp/WEB-INF/templates/catalogService.html b/tds/src/main/webapp/WEB-INF/templates/catalogService.html new file mode 100644 index 0000000000..dafad75d1e --- /dev/null +++ b/tds/src/main/webapp/WEB-INF/templates/catalogService.html @@ -0,0 +1,48 @@ + + + + + + Catalog Services + + + + + + + + +
+ Initial TDS Installation +

Initial TDS Installation (please change threddsConfig.xml)

+

THREDDS Data Server

+
+ +

Catalog http://localhost:8081/thredds/catalog/testAll/catalog.html

+

Dataset: testgrid1.nc

+
    +
  • Data size: 216.0 bytes
  • +
  • Feature type: Grid
  • +
  • ID: testDatasetScan/testgrid1.nc
  • +
+

Access:

+
    +
  1. OpenDAP: /thredds/dodsC/testAll/testgrid1.nc.html
  2. +
  3. DAP4: /thredds/dap4/testAll/testgrid1.nc.dmr.xml
  4. +
  5. HTTPServer: /thredds/fileServer/testAll/testgrid1.nc
  6. +
  7. NetcdfSubset: /thredds/ncss/grid/testAll/testgrid1.nc/dataset.html
  8. +
  9. NetcdfSubset: /thredds/ncss/point/testAll/testgrid1.nc/dataset.html
  10. +
+

Dates:

+
    +
  • 2018-06-01T19:38:51.921Z (modified)
  • +
+

Viewers:

+ + + + + diff --git a/tds/src/main/webapp/WEB-INF/templates/commonFragments.html b/tds/src/main/webapp/WEB-INF/templates/commonFragments.html index 348f4ad45e..8bb475389a 100644 --- a/tds/src/main/webapp/WEB-INF/templates/commonFragments.html +++ b/tds/src/main/webapp/WEB-INF/templates/commonFragments.html @@ -4,24 +4,14 @@ - - NetCDF Subset Service + + THREDDS Data Server - - - - - - - - - - - + + diff --git a/tds/src/main/webapp/WEB-INF/templates/gridFragments.html b/tds/src/main/webapp/WEB-INF/templates/gridFragments.html index 0c3660b971..a6465f57f9 100644 --- a/tds/src/main/webapp/WEB-INF/templates/gridFragments.html +++ b/tds/src/main/webapp/WEB-INF/templates/gridFragments.html @@ -6,7 +6,20 @@ - + + + + + + + + + + + + + + + -

Initial TDS Installation -

-
+ +

+ +
+ +

+ + - + th:if="${subset.getHref() != null}"> + - + +
Dataset Size Last Modified
     - Folder   + +      + Folder   -  ----
-

Initial TDS Installation (please change threddsConfig.xml) at My Group see Info
- THREDDS Data Server [Version $projectVersion - $buildTimestamp] Documentation

+ +
+ +

Initial TDS Installation (please change threddsConfig.xml) at My Group see Info
+ THREDDS Data Server [Version $projectVersion - $buildTimestamp] Documentation +

+ \ No newline at end of file diff --git a/tds/src/main/webapp/WEB-INF/templates/catalogFragments.html b/tds/src/main/webapp/WEB-INF/templates/catalogFragments.html new file mode 100644 index 0000000000..f688e46b1c --- /dev/null +++ b/tds/src/main/webapp/WEB-INF/templates/catalogFragments.html @@ -0,0 +1,27 @@ + + + + + + + + + + + +      + Folder   + + +   + -- + + + + + + diff --git a/tds/src/main/webapp/WEB-INF/templates/catalogService.html b/tds/src/main/webapp/WEB-INF/templates/catalogService.html deleted file mode 100644 index dafad75d1e..0000000000 --- a/tds/src/main/webapp/WEB-INF/templates/catalogService.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - Catalog Services - - - - - - - - -
- Initial TDS Installation -

Initial TDS Installation (please change threddsConfig.xml)

-

THREDDS Data Server

-
- -

Catalog http://localhost:8081/thredds/catalog/testAll/catalog.html

-

Dataset: testgrid1.nc

-
    -
  • Data size: 216.0 bytes
  • -
  • Feature type: Grid
  • -
  • ID: testDatasetScan/testgrid1.nc
  • -
-

Access:

-
    -
  1. OpenDAP: /thredds/dodsC/testAll/testgrid1.nc.html
  2. -
  3. DAP4: /thredds/dap4/testAll/testgrid1.nc.dmr.xml
  4. -
  5. HTTPServer: /thredds/fileServer/testAll/testgrid1.nc
  6. -
  7. NetcdfSubset: /thredds/ncss/grid/testAll/testgrid1.nc/dataset.html
  8. -
  9. NetcdfSubset: /thredds/ncss/point/testAll/testgrid1.nc/dataset.html
  10. -
-

Dates:

-
    -
  • 2018-06-01T19:38:51.921Z (modified)
  • -
-

Viewers:

- - - - - diff --git a/tds/src/main/webapp/WEB-INF/templates/dataset.html b/tds/src/main/webapp/WEB-INF/templates/dataset.html new file mode 100644 index 0000000000..65dce3f44d --- /dev/null +++ b/tds/src/main/webapp/WEB-INF/templates/dataset.html @@ -0,0 +1,146 @@ + + + + + + + Catalog Services + + + + + + + + +
+ +

THREDDS-DEV Data Server

+

THREDDS Data Server

+
+ +

+

+ +
+
    +
  • +
+
+ +
+

Documentation:

+
    +
  • +
  • +
+
+ +
+

Access:

+
    +
  1. +
+
+ +
+

Contributors:

+
    +
  • +
+
+ +
+

Keywords:

+
    +
  • +
+
+ +
+

Dates:

+
    +
  • +
+
+ +
+

Projects:

+
    +
  • +
+
+ +
+

Creators:

+
    +
  • +
      +
    • +
    • +
    +
  • +
+
+ +
+

Publishers:

+
    +
  • +
      +
    • +
    • +
    +
  • +
+
+ +
+

Variables:

+ +
+ +
+

GeospatialCoverage:

+
    +
  • +
  • +
  • +
+
+ +
+

TimeCoverage:

+
    +
  • +
  • +
  • +
  • +
+
+ +
+

Properties:

+
    +
  • +
  • +
+
+ +

Viewers:

+ + + \ No newline at end of file From 30e3662f84e7d76f79bf1981165fed07df2298c6 Mon Sep 17 00:00:00 2001 From: haileyajohnson Date: Tue, 12 Jun 2018 15:21:12 -0600 Subject: [PATCH 3/5] finish dataset page template and update viewer service to fit with template model cleanup refeerences to htmlwriter --- .../CatalogServiceController.java | 123 +- .../CatalogViewContextParser.java | 1134 +++++++++-------- .../RemoteCatalogServiceController.java | 10 +- .../java/thredds/server/viewer/Viewer.java | 12 +- .../thredds/server/viewer/ViewerService.java | 2 + .../server/viewer/ViewerServiceImpl.java | 56 +- .../thredds/server/wms/Godiva3Viewer.java | 66 +- .../webapp/WEB-INF/templates/catalog.html | 11 +- .../WEB-INF/templates/catalogFragments.html | 2 +- .../webapp/WEB-INF/templates/dataset.html | 150 +-- .../WEB-INF/templates/datasetFragments.html | 170 +++ 11 files changed, 945 insertions(+), 791 deletions(-) create mode 100644 tds/src/main/webapp/WEB-INF/templates/datasetFragments.html diff --git a/tds/src/main/java/thredds/server/catalogservice/CatalogServiceController.java b/tds/src/main/java/thredds/server/catalogservice/CatalogServiceController.java index f15961ec6d..036709d6e5 100644 --- a/tds/src/main/java/thredds/server/catalogservice/CatalogServiceController.java +++ b/tds/src/main/java/thredds/server/catalogservice/CatalogServiceController.java @@ -16,7 +16,6 @@ import thredds.client.catalog.Catalog; import thredds.client.catalog.Dataset; import thredds.core.CatalogManager; -import thredds.core.ConfigCatalogHtmlWriter; import thredds.core.TdsRequestedDataset; import java.io.FileNotFoundException; @@ -34,77 +33,69 @@ @Controller @RequestMapping(value = "/catalog") public class CatalogServiceController { - // private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(getClass()); - - @Autowired - private CatalogManager catalogManager; - - @Autowired - ConfigCatalogHtmlWriter writer; - - @Autowired - CatalogViewContextParser parser; - - @RequestMapping(value = "**", method = {RequestMethod.GET}) - protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response, CatalogRequest params) throws Exception { - - TdsRequestedDataset reqD = new TdsRequestedDataset(request, "/catalog"); - String path = reqD.getPath(); - boolean isHtml = path.endsWith(".html"); - String catalogPath = path.replaceAll(".html$", ".xml"); - - Catalog catalog; - URI baseUri; - String baseUriString = request.getRequestURL().toString(); - try { - baseUri = new URI(baseUriString); - catalog = catalogManager.getCatalog(catalogPath, baseUri); - - } catch (URISyntaxException e) { - String msg = "Bad URI syntax [" + baseUriString + "]: " + e.getMessage(); - throw new URISyntaxException(msg, e.getReason()); - } - - // no catalog found - if (catalog == null) - throw new FileNotFoundException(request.getRequestURI()); - - if (isHtml) { - return handleHTMLRequest(request, response, catalog, params); - } else { - return handleXMLRequest(request, response, catalog, params); - } - } + // private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(getClass()); + + @Autowired + private CatalogManager catalogManager; + + @Autowired + CatalogViewContextParser parser; + + @RequestMapping(value = "**", method = {RequestMethod.GET}) + protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response, CatalogRequest params) throws Exception { + + TdsRequestedDataset reqD = new TdsRequestedDataset(request, "/catalog"); + String path = reqD.getPath(); + boolean isHtml = path.endsWith(".html"); + String catalogPath = path.replaceAll(".html$", ".xml"); - protected ModelAndView handleXMLRequest(HttpServletRequest request, HttpServletResponse response, Catalog catalog, CatalogRequest params) throws Exception { - if (params.dataset != null) { - Dataset dataset = catalog.findDatasetByID(params.dataset); - if (dataset == null) - throw new FileNotFoundException("Did not find dataset [" + params.dataset + "] in catalog [" + request.getRequestURL().toString() + "]."); + Catalog catalog; + URI baseUri; + String baseUriString = request.getRequestURL().toString(); + try { + baseUri = new URI(baseUriString); + catalog = catalogManager.getCatalog(catalogPath, baseUri); - Catalog subsetCat = catalog.subsetCatalogOnDataset(dataset); - return new ModelAndView("threddsInvCatXmlView", "catalog", subsetCat); + } catch (URISyntaxException e) { + String msg = "Bad URI syntax [" + baseUriString + "]: " + e.getMessage(); + throw new URISyntaxException(msg, e.getReason()); + } + + // no catalog found + if (catalog == null) + throw new FileNotFoundException(request.getRequestURI()); - } else { - return new ModelAndView("threddsInvCatXmlView", "catalog", catalog); - } + if (isHtml) { + return handleHTMLRequest(request, response, catalog, params); + } else { + return handleXMLRequest(request, response, catalog, params); } + } + + protected ModelAndView handleXMLRequest(HttpServletRequest request, HttpServletResponse response, Catalog catalog, CatalogRequest params) throws Exception { + if (params.dataset != null) { + Dataset dataset = catalog.findDatasetByID(params.dataset); + if (dataset == null) + throw new FileNotFoundException("Did not find dataset [" + params.dataset + "] in catalog [" + request.getRequestURL().toString() + "]."); - protected ModelAndView handleHTMLRequest(HttpServletRequest request, HttpServletResponse response, Catalog catalog, CatalogRequest params) throws Exception { - if (params.dataset != null) { - Dataset dataset = catalog.findDatasetByID(params.dataset); - if (dataset == null) - throw new FileNotFoundException("Did not find dataset [" + params.dataset + "] in catalog [" + request.getRequestURL().toString() + "]."); -// -// Catalog subsetCat = catalog.subsetCatalogOnDataset(dataset); - -// int i = writer.showDataset(request.getRequestURL().toString(), dataset, request, response, true); -// return null; - return new ModelAndView("templates/dataset", parser.getDatasetViewContext(dataset, true)); - } else { - return new ModelAndView("templates/catalog", parser.getCatalogViewContext(catalog, true)); - } + Catalog subsetCat = catalog.subsetCatalogOnDataset(dataset); + return new ModelAndView("threddsInvCatXmlView", "catalog", subsetCat); + + } else { + return new ModelAndView("threddsInvCatXmlView", "catalog", catalog); + } + } + + protected ModelAndView handleHTMLRequest(HttpServletRequest request, HttpServletResponse response, Catalog catalog, CatalogRequest params) throws Exception { + if (params.dataset != null) { + Dataset dataset = catalog.findDatasetByID(params.dataset); + if (dataset == null) + throw new FileNotFoundException("Did not find dataset [" + params.dataset + "] in catalog [" + request.getRequestURL().toString() + "]."); + return new ModelAndView("templates/dataset", parser.getDatasetViewContext(dataset, request,true)); + } else { + return new ModelAndView("templates/catalog", parser.getCatalogViewContext(catalog, true)); } + } /* private ModelAndView handlePublicDocumentRequest(HttpServletRequest request, HttpServletResponse response, String path) throws IOException, ServletException { diff --git a/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java b/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java index c378171cfa..4adfd56c5e 100644 --- a/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java +++ b/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java @@ -9,703 +9,721 @@ import thredds.server.config.HtmlConfigBean; import thredds.server.config.TdsContext; import thredds.server.config.TdsServerInfoBean; -import ucar.nc2.stream.NcStreamProto; +import thredds.server.viewer.Viewer; +import thredds.server.viewer.ViewerLinkProvider; +import thredds.server.viewer.ViewerService; import ucar.nc2.units.DateType; import ucar.nc2.units.DateRange; import ucar.nc2.units.TimeDuration; import ucar.unidata.util.Format; import ucar.unidata.util.StringUtil2; +import javax.servlet.http.HttpServletRequest; import java.net.URI; import java.util.*; @Component public class CatalogViewContextParser { - @Autowired - private HtmlConfigBean htmlConfig; + @Autowired + private ViewerService viewerService; - @Autowired - private TdsContext tdsContext; + @Autowired + private HtmlConfigBean htmlConfig; - @Autowired - private TdsServerInfoBean serverInfo; + @Autowired + private TdsContext tdsContext; - public Map getCatalogViewContext(Catalog cat, boolean isLocalCatalog) { - Map model = new HashMap<>(); - model.put("googleTracking", htmlConfig.getGoogleTrackingCode()); + @Autowired + private TdsServerInfoBean serverInfo; - // parse basic catalog context -// String uri = cat.getUriString(); -// String name = cat.getName(); -// if (uri == null) uri = name; -// if (uri == null) uri = "unknown"; -// model.put("uri", uri); -// if (name == null) name = uri; -// model.put("name", cat.getName()); + public Map getCatalogViewContext(Catalog cat, boolean isLocalCatalog) { + Map model = new HashMap<>(); + String googleTrackingCode = htmlConfig.getGoogleTrackingCode(); + if (googleTrackingCode.isEmpty()) googleTrackingCode = null; + model.put("googleTracking", googleTrackingCode); - model.put("serverName", serverInfo.getName()); - model.put("logoUrl", serverInfo.getLogoUrl()); - model.put("logoAlt", serverInfo.getLogoAltText()); + model.put("serverName", serverInfo.getName()); + model.put("logoUrl", serverInfo.getLogoUrl()); + model.put("logoAlt", serverInfo.getLogoAltText()); - List catalogItems = new ArrayList<>(); - addCatalogItems(cat, catalogItems, isLocalCatalog, 0); - model.put("items", catalogItems); - return model; - } + List catalogItems = new ArrayList<>(); + addCatalogItems(cat, catalogItems, isLocalCatalog, 0); + model.put("items", catalogItems); + return model; + } - public Map getDatasetViewContext(Dataset ds, boolean isLocalCatalog) - { - Map model = new HashMap<>(); + public Map getDatasetViewContext(Dataset ds, HttpServletRequest req, boolean isLocalCatalog) + { + Map model = new HashMap<>(); - model.put("googleTracking", htmlConfig.getGoogleTrackingCode()); - model.put("serverName", serverInfo.getName()); - model.put("logoUrl", serverInfo.getLogoUrl()); - model.put("logoAlt", serverInfo.getLogoAltText()); - model.put("installName", htmlConfig.getInstallName()); - model.put("installUrl", htmlConfig.getInstallUrl()); - model.put("webappName", htmlConfig.getWebappName()); - model.put("webappUrl", htmlConfig.getWebappUrl()); + model.put("googleTracking", htmlConfig.getGoogleTrackingCode()); + model.put("serverName", serverInfo.getName()); + model.put("logoUrl", serverInfo.getLogoUrl()); + model.put("logoAlt", serverInfo.getLogoAltText()); + model.put("installName", htmlConfig.getInstallName()); + model.put("installUrl", htmlConfig.getInstallUrl()); + model.put("webappName", htmlConfig.getWebappName()); + model.put("webappUrl", htmlConfig.getWebappUrl()); - DatasetContext context = new DatasetContext(ds, isLocalCatalog); - populateDatasetContext(ds, context, isLocalCatalog); + DatasetContext context = new DatasetContext(ds, isLocalCatalog); + populateDatasetContext(ds, context, req, isLocalCatalog); - model.put("dataset", context); + model.put("dataset", context); - return model; - } + return model; + } - protected void addCatalogItems(DatasetNode cat, List catalogItems, boolean isLocalCatalog, int level) - { - for (Dataset ds : cat.getDatasets()) { - populateItemContext(ds, catalogItems, isLocalCatalog, level); - } + protected void addCatalogItems(DatasetNode cat, List catalogItems, boolean isLocalCatalog, int level) + { + for (Dataset ds : cat.getDatasets()) { + populateItemContext(ds, catalogItems, isLocalCatalog, level); } + } - protected void populateItemContext(Dataset ds, List catalogItems, boolean isLocalCatalog, int level) { - CatalogItemContext context = new CatalogItemContext(ds, level); + protected void populateItemContext(Dataset ds, List catalogItems, boolean isLocalCatalog, int level) { + CatalogItemContext context = new CatalogItemContext(ds, level); - // add item href - context.setHref(getCatalogItemHref(ds, isLocalCatalog)); + // add item href + context.setHref(getCatalogItemHref(ds, isLocalCatalog)); - // add item icon - context.setIconSrc(getFolderIconSrc(ds)); + // add item icon + context.setIconSrc(getFolderIconSrc(ds)); - // add item to Catalog - catalogItems.add(context); + // add item to Catalog + catalogItems.add(context); - // recursively add subdirectories - if (!(ds instanceof CatalogRef)) { - addCatalogItems(ds, catalogItems, isLocalCatalog, level + 1); - } + // recursively add subdirectories + if (!(ds instanceof CatalogRef)) { + addCatalogItems(ds, catalogItems, isLocalCatalog, level + 1); } + } - protected void populateDatasetContext(Dataset ds, DatasetContext context, boolean isLocalCatalog) { - if (ds instanceof CatalogRef) { - CatalogRef catref = (CatalogRef) ds; - context.addContextItem("href", getCatalogRefHref(catref, isLocalCatalog)); - } - - // TODO: add viewers - // optional access through Viewers -// if (isLocalCatalog) -// viewerService.showViewers(out, dataset, request); + protected void populateDatasetContext(Dataset ds, DatasetContext context, HttpServletRequest req, boolean isLocalCatalog) { + if (ds instanceof CatalogRef) { + CatalogRef catref = (CatalogRef) ds; + context.addContextItem("href", getCatalogRefHref(catref, isLocalCatalog)); } - private String getCatalogItemHref(Dataset ds, boolean isLocalCatalog) - { - if (ds instanceof CatalogRef) { - CatalogRef catref = (CatalogRef) ds; - String href = catref.getXlinkHref(); - if (!isLocalCatalog) { - URI hrefUri = ds.getParentCatalog().getBaseURI().resolve(href); - href = hrefUri.toString(); - } - try { - URI uri = new URI(href); - if (uri.isAbsolute()) { - boolean defaultUseRemoteCatalogService = htmlConfig.getUseRemoteCatalogService(); // read default as set in threddsConfig.xml - Boolean dsUseRemoteCatalogService = ((CatalogRef) ds).useRemoteCatalogService(); // check to see if catalogRef contains tag that overrides default - boolean useRemoteCatalogService = defaultUseRemoteCatalogService; // by default, use the option found in threddsConfig.xml - if (dsUseRemoteCatalogService == null) - dsUseRemoteCatalogService = defaultUseRemoteCatalogService; // if the dataset does not have the useRemoteDataset option set, opt for the default behavior - - // if the default is not the same as what is defined in the catalog, go with the catalog option - // as the user has explicitly overridden the default - if (defaultUseRemoteCatalogService != dsUseRemoteCatalogService) { - useRemoteCatalogService = dsUseRemoteCatalogService; - } - - // now, do the right thing with using the remoteCatalogService, or not - if (useRemoteCatalogService) { - href = tdsContext.getContextPath() + "/remoteCatalogService?catalog=" + href; - } else { - int pos = href.lastIndexOf('.'); - href = href.substring(0, pos) + ".html"; - } - } else { - int pos = href.lastIndexOf('.'); - href = href.substring(0, pos) + ".html"; - } - - } catch (Exception e) {//(URISyntaxException e) { - //log.error(href, e); - } - - return href; - - } else { // Not a CatalogRef - // Check if dataset has single resolver service. - if (ds.getAccess().size() == 1 && ServiceType.Resolver == ds.getAccess().get(0).getService().getType()) { - Access access = ds.getAccess().get(0); - String accessUrlName = access.getUnresolvedUrlName(); - int pos = accessUrlName.lastIndexOf(".xml"); - - if (accessUrlName.equalsIgnoreCase("latest.xml") && !isLocalCatalog) { - String catBaseUriPath = ""; - String catBaseUri = ds.getParentCatalog().getBaseURI().toString(); - pos = catBaseUri.lastIndexOf("catalog.xml"); - if (pos != -1) { - catBaseUriPath = catBaseUri.substring(0, pos); - } - accessUrlName = tdsContext.getContextPath() + "/remoteCatalogService?catalog=" + catBaseUriPath + accessUrlName; - } else if (pos != -1) { - accessUrlName = accessUrlName.substring(0, pos) + ".html"; - } - return accessUrlName; - - } else if (ds.findProperty(Dataset.NotAThreddsDataset) != null) { // Dataset can only be file served - // Write link to HTML dataset page. - return makeFileServerUrl(ds); - - } else if (ds.getID() != null) { // Dataset with an ID. //URI catURI = cat.getBaseURI(); - Catalog cat = ds.getParentCatalog(); - String catHtml; - if (!isLocalCatalog) { - // Setup HREF url to link to HTML dataset page (more below). - catHtml = tdsContext.getContextPath() + "/remoteCatalogService?command=" + RemoteCatalogRequest.Command.SUBSET + "&catalog=" + cat.getUriString() + "&"; - // Can't be "/catalogServices?..." because subset decides on xml or html by trailing ".html" on URL path - } else { // replace xml with html - URI catURI = cat.getBaseURI(); - // Get the catalog name - we want a relative URL - catHtml = catURI.getPath(); - if (catHtml == null) catHtml = cat.getUriString(); // if URI is a file - int pos = catHtml.lastIndexOf("/"); - if (pos != -1) catHtml = catHtml.substring(pos + 1); - // change the ending to "catalog.html?" - pos = catHtml.lastIndexOf('.'); - if (pos < 0) - catHtml = catHtml + "catalog.html?"; - else - catHtml = catHtml.substring(0, pos) + ".html?"; - } - - // Write link to HTML dataset page. - return catHtml + "dataset=" + StringUtil2.replace(ds.getID(), '+', "%2B"); - } else { - return null; - } + if (isLocalCatalog) context.setViewers(ds, viewerService.getViewerLinks(ds, req)); + } + + private String getCatalogItemHref(Dataset ds, boolean isLocalCatalog) + { + if (ds instanceof CatalogRef) { + CatalogRef catref = (CatalogRef) ds; + String href = catref.getXlinkHref(); + if (!isLocalCatalog) { + URI hrefUri = ds.getParentCatalog().getBaseURI().resolve(href); + href = hrefUri.toString(); + } + try { + URI uri = new URI(href); + if (uri.isAbsolute()) { + boolean defaultUseRemoteCatalogService = htmlConfig.getUseRemoteCatalogService(); // read default as set in threddsConfig.xml + Boolean dsUseRemoteCatalogService = ((CatalogRef) ds).useRemoteCatalogService(); // check to see if catalogRef contains tag that overrides default + boolean useRemoteCatalogService = defaultUseRemoteCatalogService; // by default, use the option found in threddsConfig.xml + if (dsUseRemoteCatalogService == null) + dsUseRemoteCatalogService = defaultUseRemoteCatalogService; // if the dataset does not have the useRemoteDataset option set, opt for the default behavior + + // if the default is not the same as what is defined in the catalog, go with the catalog option + // as the user has explicitly overridden the default + if (defaultUseRemoteCatalogService != dsUseRemoteCatalogService) { + useRemoteCatalogService = dsUseRemoteCatalogService; + } + + // now, do the right thing with using the remoteCatalogService, or not + if (useRemoteCatalogService) { + href = tdsContext.getContextPath() + "/remoteCatalogService?catalog=" + href; + } else { + int pos = href.lastIndexOf('.'); + href = href.substring(0, pos) + ".html"; + } + } else { + int pos = href.lastIndexOf('.'); + href = href.substring(0, pos) + ".html"; } - } - private String getCatalogRefHref(CatalogRef catref, boolean isLocalCatalog) { - String href = catref.getXlinkHref(); - if (!isLocalCatalog) { - href = CatalogViewContextParser.makeHrefResolve((Dataset) catref, href); + } catch (Exception e) {//(URISyntaxException e) { + //log.error(href, e); + } + + return href; + + } else { // Not a CatalogRef + // Check if dataset has single resolver service. + if (ds.getAccess().size() == 1 && ServiceType.Resolver == ds.getAccess().get(0).getService().getType()) { + Access access = ds.getAccess().get(0); + String accessUrlName = access.getUnresolvedUrlName(); + int pos = accessUrlName.lastIndexOf(".xml"); + + if (accessUrlName.equalsIgnoreCase("latest.xml") && !isLocalCatalog) { + String catBaseUriPath = ""; + String catBaseUri = ds.getParentCatalog().getBaseURI().toString(); + pos = catBaseUri.lastIndexOf("catalog.xml"); + if (pos != -1) { + catBaseUriPath = catBaseUri.substring(0, pos); + } + accessUrlName = tdsContext.getContextPath() + "/remoteCatalogService?catalog=" + catBaseUriPath + accessUrlName; + } else if (pos != -1) { + accessUrlName = accessUrlName.substring(0, pos) + ".html"; } - return href; - } - protected static String makeHrefResolve(Dataset ds, String href) { - Catalog cat = ds.getParentCatalog(); - if (cat != null) { - try { - java.net.URI uri = cat.resolveUri(href); - href = uri.toString(); - } catch (java.net.URISyntaxException e) { - return "CatalogViewContextParser: error parsing URL= " + href; - } - } - return href; - } + return accessUrlName; + + } else if (ds.findProperty(Dataset.NotAThreddsDataset) != null) { // Dataset can only be file served + // Write link to HTML dataset page. + return makeFileServerUrl(ds); - private String getFolderIconSrc(Dataset ds) { - String iconSrc = null; - if (ds instanceof CatalogRef) { - if (ds instanceof CatalogScan || ds.hasProperty("CatalogScan")) - iconSrc = "cat_folder.png"; - else if (ds instanceof DatasetScan || ds.hasProperty("DatasetScan")) - iconSrc = "scan_folder.png"; - else if (ds instanceof FeatureCollectionRef) - iconSrc = "fc_folder.png"; - else - iconSrc = "folder.png"; - - } else { // Not a CatalogRef - if (ds.hasNestedDatasets()) - iconSrc = "folder.png"; + } else if (ds.getID() != null) { // Dataset with an ID. //URI catURI = cat.getBaseURI(); + Catalog cat = ds.getParentCatalog(); + String catHtml; + if (!isLocalCatalog) { + // Setup HREF url to link to HTML dataset page (more below). + catHtml = tdsContext.getContextPath() + "/remoteCatalogService?command=" + RemoteCatalogRequest.Command.SUBSET + "&catalog=" + cat.getUriString() + "&"; + // Can't be "/catalogServices?..." because subset decides on xml or html by trailing ".html" on URL path + } else { // replace xml with html + URI catURI = cat.getBaseURI(); + // Get the catalog name - we want a relative URL + catHtml = catURI.getPath(); + if (catHtml == null) catHtml = cat.getUriString(); // if URI is a file + int pos = catHtml.lastIndexOf("/"); + if (pos != -1) catHtml = catHtml.substring(pos + 1); + // change the ending to "catalog.html?" + pos = catHtml.lastIndexOf('.'); + if (pos < 0) + catHtml = catHtml + "catalog.html?"; + else + catHtml = catHtml.substring(0, pos) + ".html?"; } - if (iconSrc != null) iconSrc = htmlConfig.prepareUrlStringForHtml(iconSrc); - return iconSrc; + // Write link to HTML dataset page. + return catHtml + "dataset=" + StringUtil2.replace(ds.getID(), '+', "%2B"); + } else { + return null; + } } + } - private String makeFileServerUrl(Dataset ds) { - Access acc = ds.getAccess(ServiceType.HTTPServer); - assert acc != null; - return acc.getStandardUrlName(); + private String getCatalogRefHref(CatalogRef catref, boolean isLocalCatalog) { + String href = catref.getXlinkHref(); + if (!isLocalCatalog) { + href = CatalogViewContextParser.makeHrefResolve((Dataset) catref, href); + } + return href; + } + protected static String makeHrefResolve(Dataset ds, String href) { + Catalog cat = ds.getParentCatalog(); + if (cat != null) { + try { + java.net.URI uri = cat.resolveUri(href); + href = uri.toString(); + } catch (java.net.URISyntaxException e) { + return "CatalogViewContextParser: error parsing URL= " + href; + } } + return href; + } + + private String getFolderIconSrc(Dataset ds) { + String iconSrc = null; + if (ds instanceof CatalogRef) { + if (ds instanceof CatalogScan || ds.hasProperty("CatalogScan")) + iconSrc = "cat_folder.png"; + else if (ds instanceof DatasetScan || ds.hasProperty("DatasetScan")) + iconSrc = "scan_folder.png"; + else if (ds instanceof FeatureCollectionRef) + iconSrc = "fc_folder.png"; + else + iconSrc = "folder.png"; + + } else { // Not a CatalogRef + if (ds.hasNestedDatasets()) + iconSrc = "folder.png"; + } + + if (iconSrc != null) iconSrc = htmlConfig.prepareUrlStringForHtml(iconSrc); + return iconSrc; + } + + private String makeFileServerUrl(Dataset ds) { + Access acc = ds.getAccess(ServiceType.HTTPServer); + assert acc != null; + return acc.getStandardUrlName(); + } } class CatalogItemContext { - //static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CatalogItemContext.class); + //static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CatalogItemContext.class); - private String displayName; - private int level; - private String dataSize; - private String lastModified; - private String iconSrc; - private String itemhref; + private String displayName; + private int level; + private String dataSize; + private String lastModified; + private String iconSrc; + private String itemhref; - public CatalogItemContext(Dataset ds, int level) - { - // Get display name - this.displayName = ds.getName(); + public CatalogItemContext(Dataset ds, int level) + { + // Get display name + this.displayName = ds.getName(); - // Get data size - double size = ds.getDataSize(); - if ((size > 0) && !Double.isNaN(size)) - this.dataSize = (Format.formatByteSize(size)); + // Get data size + double size = ds.getDataSize(); + if ((size > 0) && !Double.isNaN(size)) + this.dataSize = (Format.formatByteSize(size)); - // Get last modified time. - DateType lastModDateType = ds.getLastModifiedDate(); - if (lastModDateType != null) - this.lastModified = lastModDateType.toDateTimeString(); + // Get last modified time. + DateType lastModDateType = ds.getLastModifiedDate(); + if (lastModDateType != null) + this.lastModified = lastModDateType.toDateTimeString(); - // Store nesting level - this.level = level; - } + // Store nesting level + this.level = level; + } - public String getDisplayName() { return this.displayName; } + public String getDisplayName() { return this.displayName; } - public int getLevel() { return this.level; } + public int getLevel() { return this.level; } - public String getDataSize() { return this.dataSize; } + public String getDataSize() { return this.dataSize; } - public String getLastModified() { return this.lastModified; } + public String getLastModified() { return this.lastModified; } - public String getIconSrc() { return this.iconSrc; } + public String getIconSrc() { return this.iconSrc; } - public void setIconSrc(String iconSrc) { this.iconSrc = iconSrc; } + public void setIconSrc(String iconSrc) { this.iconSrc = iconSrc; } - public String getHref() { return this.itemhref; } + public String getHref() { return this.itemhref; } - public void setHref(String href) { this.itemhref = href; } + public void setHref(String href) { this.itemhref = href; } } class DatasetContext { - private String name; + private String name; - private String catUrl; + private String catUrl; - private Map context; + private Map context; - private List> documentation; + private List> documentation; - private List> access; + private List> access; - private List> contributors; + private List> contributors; - private List> keywords; + private List> keywords; - private List> dates; + private List> dates; - private List> projects; + private List> projects; - private List> creators; + private List> creators; - private List> publishers; + private List> publishers; - private List> variables; + private List> variables; - private String variableMapLink; + private String variableMapLink; - private Map geospatialCoverage; + private Map geospatialCoverage; - private Map timeCoverage; + private Map timeCoverage; - private List> metadata; + private List> metadata; - private List> properties; + private List> properties; + private List> viewerLinks; - // TODO: viewers - public DatasetContext(Dataset ds, boolean isLocalCatalog) { - // Get display name can catalog url - this.name = ds.getName(); - this.catUrl = ds.getCatalogUrl(); + // TODO: viewers - setContext(ds); - setDocumentation(ds); - setAccess(ds, isLocalCatalog); - setContributors(ds); - setKeywords(ds); - setDates(ds); - setProjects(ds); - setCreators(ds, isLocalCatalog); - setPublishers(ds, isLocalCatalog); - setVariables(ds, isLocalCatalog); - setGeospatialCoverage(ds); - setTimeCoverage(ds); - setMetadata(ds, isLocalCatalog); - setProperties(ds, isLocalCatalog); - } + public DatasetContext(Dataset ds, boolean isLocalCatalog) { + // Get display name can catalog url + this.name = ds.getName(); + this.catUrl = ds.getCatalogUrl(); - private void setContext(Dataset ds) { - this.context = new HashMap<>(); + setContext(ds); + setDocumentation(ds); + setAccess(ds, isLocalCatalog); + setContributors(ds); + setKeywords(ds); + setDates(ds); + setProjects(ds); + setCreators(ds, isLocalCatalog); + setPublishers(ds, isLocalCatalog); + setVariables(ds, isLocalCatalog); + setGeospatialCoverage(ds); + setTimeCoverage(ds); + setMetadata(ds, isLocalCatalog); + setProperties(ds, isLocalCatalog); - String dataFormat = ds.getDataFormatName(); - if (dataFormat != null) context.put("dataFormat", dataFormat); + this.viewerLinks = new ArrayList<>(); + } - long dataSize = ds.getDataSize(); - if (dataSize > 0) context.put("dataSize", dataSize); + private void setContext(Dataset ds) { + this.context = new HashMap<>(); - String featureType = ds.getFeatureTypeName(); - if (featureType != null) context.put("featureType", featureType); + String dataFormat = ds.getDataFormatName(); + if (dataFormat != null) context.put("dataFormat", dataFormat); - String collectionType = ds.getCollectionType(); - if (collectionType != null) context.put("collectionType", collectionType); + long dataSize = ds.getDataSize(); + if (dataSize > 0) context.put("dataSize", dataSize); - boolean isHarvest = ds.isHarvest(); - if (isHarvest) context.put("isHarvest", true); + String featureType = ds.getFeatureTypeName(); + if (featureType != null) context.put("featureType", featureType); - String authority = ds.getAuthority(); - if (authority != null) context.put("authority", authority); + String collectionType = ds.getCollectionType(); + if (collectionType != null) context.put("collectionType", collectionType); - String id = ds.getId(); - if (id != null) context.put("id", id); + boolean isHarvest = ds.isHarvest(); + if (isHarvest) context.put("isHarvest", true); - String restrictAccess = ds.getRestrictAccess(); - if (restrictAccess != null) context.put("restrictAccess", restrictAccess); - } + String authority = ds.getAuthority(); + if (authority != null) context.put("authority", authority); - private void setDocumentation(Dataset ds) { - java.util.List docs = ds.getDocumentation(); - this.documentation = new ArrayList<>(docs.size()); - - for (Documentation doc : docs) { - Map docMap = new HashMap<>(); - docMap.put("inlineContent", doc.getInlineContent()); - String type = doc.getType(); - if (type == null) type = ""; - docMap.put("type", type); - if (doc.hasXlink()) { - docMap.put("href", doc.getXlinkHref()); - docMap.put("title", doc.getXlinkTitle()); - } - this.documentation.add(docMap); - } - } + String id = ds.getId(); + if (id != null) context.put("id", id); - private void setAccess(Dataset ds, boolean isLocalCatalog) { - List access = ds.getAccess(); - this.access = new ArrayList<>(access.size()); - - for (Access a : access) { - Service s = a.getService(); - String urlString = !isLocalCatalog ? a.getStandardUrlName() : a.getUnresolvedUrlName(); - String queryString = null; - // String fullUrlString = urlString; - - ServiceType stype = s.getType(); - if (stype != null) { - switch (stype) { - case OPENDAP: - case DODS: - urlString = urlString + ".html"; - break; - - case DAP4: - urlString = urlString + ".dmr.xml"; - break; - - case WCS: - queryString = "service=WCS&version=1.0.0&request=GetCapabilities"; - break; - - case WMS: - queryString = "service=WMS&version=1.3.0&request=GetCapabilities"; - break; - - case NCML: - case UDDC: - case ISO: - String catalogUrl = ds.getCatalogUrl(); - String datasetId = ds.getId(); - if (catalogUrl != null && datasetId != null) { - if (catalogUrl.indexOf('#') > 0) - catalogUrl = catalogUrl.substring(0, catalogUrl.lastIndexOf('#')); - queryString = "catalog=" + catalogUrl + "&dataset=" + datasetId; - } - break; - - case NetcdfSubset: - urlString = urlString + "/dataset.html"; - break; - - case CdmRemote: - queryString = "req=cdl"; - break; - case CdmrFeature: - queryString = "req=form"; - } - } - Map accessMap = new HashMap<>(); - accessMap.put("serviceTypeName", s.getServiceTypeName()); - accessMap.put("href", queryString == null ? urlString : urlString + "?" + queryString); - this.access.add(accessMap); - } - } - private void setContributors(Dataset ds) { - java.util.List contributors = ds.getContributors(); - this.contributors = new ArrayList<>(contributors.size()); - - for (ThreddsMetadata.Contributor t : contributors) { - Map contribMap = new HashMap<>(); - contribMap.put("role", t.getRole() == null ? "" : t.getRole()); - contribMap.put("name", t.getName()); - this.contributors.add(contribMap); - } - } + String restrictAccess = ds.getRestrictAccess(); + if (restrictAccess != null) context.put("restrictAccess", restrictAccess); + } - private void setKeywords(Dataset ds) { - java.util.List keywords = ds.getKeywords(); - this.keywords = new ArrayList<>(keywords.size()); + private void setDocumentation(Dataset ds) { + java.util.List docs = ds.getDocumentation(); + this.documentation = new ArrayList<>(docs.size()); - for (ThreddsMetadata.Vocab t : keywords) { - Map keyMap = new HashMap<>(); - keyMap.put("vocab", t.getVocabulary() == null ? "" : t.getVocabulary()); - keyMap.put("text", t.getText()); - this.keywords.add(keyMap); - } + for (Documentation doc : docs) { + Map docMap = new HashMap<>(); + String inlineContent = doc.getInlineContent(); + if (inlineContent.isEmpty()) inlineContent = null; + docMap.put("inlineContent", inlineContent); + String type = doc.getType(); + if (type == null) type = ""; + docMap.put("type", type); + if (doc.hasXlink()) { + docMap.put("href", doc.getXlinkHref()); + docMap.put("title", doc.getXlinkTitle()); + } + this.documentation.add(docMap); } + } + + private void setAccess(Dataset ds, boolean isLocalCatalog) { + List access = ds.getAccess(); + this.access = new ArrayList<>(access.size()); + + for (Access a : access) { + Service s = a.getService(); + String urlString = !isLocalCatalog ? a.getStandardUrlName() : a.getUnresolvedUrlName(); + String queryString = null; + // String fullUrlString = urlString; + + ServiceType stype = s.getType(); + if (stype != null) { + switch (stype) { + case OPENDAP: + case DODS: + urlString = urlString + ".html"; + break; + + case DAP4: + urlString = urlString + ".dmr.xml"; + break; + + case WCS: + queryString = "service=WCS&version=1.0.0&request=GetCapabilities"; + break; + + case WMS: + queryString = "service=WMS&version=1.3.0&request=GetCapabilities"; + break; + + case NCML: + case UDDC: + case ISO: + String catalogUrl = ds.getCatalogUrl(); + String datasetId = ds.getId(); + if (catalogUrl != null && datasetId != null) { + if (catalogUrl.indexOf('#') > 0) + catalogUrl = catalogUrl.substring(0, catalogUrl.lastIndexOf('#')); + queryString = "catalog=" + catalogUrl + "&dataset=" + datasetId; + } + break; - private void setDates(Dataset ds) { - java.util.List dates = ds.getDates(); - this.dates = new ArrayList<>(dates.size()); + case NetcdfSubset: + urlString = urlString + "/dataset.html"; + break; - for (DateType d : dates) { - Map dateMap = new HashMap<>(); - dateMap.put("type", d.getType() == null ? "" : d.getType()); - dateMap.put("text", d.getText()); - this.dates.add(dateMap); + case CdmRemote: + queryString = "req=cdl"; + break; + case CdmrFeature: + queryString = "req=form"; } + } + Map accessMap = new HashMap<>(); + accessMap.put("serviceTypeName", s.getServiceTypeName()); + accessMap.put("href", queryString == null ? urlString : urlString + "?" + queryString); + this.access.add(accessMap); + } + } + private void setContributors(Dataset ds) { + java.util.List contributors = ds.getContributors(); + this.contributors = new ArrayList<>(contributors.size()); + + for (ThreddsMetadata.Contributor t : contributors) { + Map contribMap = new HashMap<>(); + contribMap.put("role", t.getRole() == null ? "" : t.getRole()); + contribMap.put("name", t.getName()); + this.contributors.add(contribMap); } + } - private void setProjects(Dataset ds) { - java.util.List projects = ds.getProjects(); - this.projects = new ArrayList<>(projects.size()); + private void setKeywords(Dataset ds) { + java.util.List keywords = ds.getKeywords(); + this.keywords = new ArrayList<>(keywords.size()); - for (ThreddsMetadata.Vocab t : projects) { - Map projectMap = new HashMap<>(); - projectMap.put("vocab", t.getVocabulary() == null ? "" : t.getVocabulary()); - projectMap.put("text", t.getText()); - this.projects.add(projectMap); - } + for (ThreddsMetadata.Vocab t : keywords) { + Map keyMap = new HashMap<>(); + keyMap.put("vocab", t.getVocabulary() == null ? "" : t.getVocabulary()); + keyMap.put("text", t.getText()); + this.keywords.add(keyMap); } + } - private void setCreators(Dataset ds, boolean isLocalCatalog) { - java.util.List creators = ds.getCreators(); - this.creators = new ArrayList<>(creators.size()); - - for (ThreddsMetadata.Source t : creators) { - Map creatorMap = new HashMap<>(); - creatorMap.put("name", t.getName()); - creatorMap.put("email", t.getEmail()); - String href = t.getUrl(); - if (!isLocalCatalog) href = CatalogViewContextParser.makeHrefResolve(ds, href); - creatorMap.put("href", href); - this.creators.add(creatorMap); - } - } + private void setDates(Dataset ds) { + java.util.List dates = ds.getDates(); + this.dates = new ArrayList<>(dates.size()); - private void setPublishers(Dataset ds, boolean isLocalCatalog) { - this.publishers = new ArrayList<>(); - java.util.List publishers = ds.getPublishers(); - - for (ThreddsMetadata.Source t : publishers) { - Map pubMap = new HashMap<>(); - pubMap.put("name", t.getName()); - pubMap.put("email", t.getEmail()); - String href = t.getUrl(); - if (!isLocalCatalog) href = CatalogViewContextParser.makeHrefResolve(ds, href); - pubMap.put("href", href); - this.publishers.add(pubMap); - } + for (DateType d : dates) { + Map dateMap = new HashMap<>(); + dateMap.put("type", d.getType() == null ? "" : d.getType()); + dateMap.put("text", d.getText()); + this.dates.add(dateMap); } + } - // TODO: this structure is wrong yo... - private void setVariables(Dataset ds, boolean isLocalCatalog) { - List vars = ds.getVariables(); - this.variables = new ArrayList<>(vars.size()); - - for (ThreddsMetadata.VariableGroup t : vars) { - Map varGroup = new HashMap(); - String vocab = t.getVocabulary(); - varGroup.put("title", vocab); - ThreddsMetadata.UriResolved vocabUri = t.getVocabUri(); - if (vocabUri != null) { - varGroup.put("href", isLocalCatalog ? vocabUri.href : vocabUri.resolved.toString()); - } + private void setProjects(Dataset ds) { + java.util.List projects = ds.getProjects(); + this.projects = new ArrayList<>(projects.size()); - List> varList = new ArrayList<>(); - List vlist = t.getVariableList(); - for (ThreddsMetadata.Variable v : vlist) { - Map var= new HashMap<>(); - String units = (v.getUnits() == null || v.getUnits().length() == 0) ? "" : " (" + v.getUnits() + ") "; - var.put("nameAndUnits", v.getName() + units); - var.put("description", v.getDescription()); - var.put("vocabularyName", v.getVocabularyName()); - varList.add(var); - } - varGroup.put("varList", varList); - this.variables.add(varGroup); - } - - // LOOK what about VariableMapLink string ?? - ThreddsMetadata.UriResolved uri = ds.getVariableMapLink(); - if (uri != null) { - this.variableMapLink = uri.resolved.toASCIIString(); - } + for (ThreddsMetadata.Vocab t : projects) { + Map projectMap = new HashMap<>(); + projectMap.put("vocab", t.getVocabulary() == null ? "" : t.getVocabulary()); + projectMap.put("text", t.getText()); + this.projects.add(projectMap); } - - private void setGeospatialCoverage(Dataset ds) { - ThreddsMetadata.GeospatialCoverage gc = ds.getGeospatialCoverage(); - if (gc != null) { - this.geospatialCoverage = new HashMap<>(); - this.geospatialCoverage.put("eastWestRange", rangeString(gc.getEastWestRange())); - this.geospatialCoverage.put("northSouthRange", rangeString(gc.getNorthSouthRange())); - this.geospatialCoverage.put("upDownRange", rangeString(gc.getUpDownRange())); - this.geospatialCoverage.put("zPositive", gc.getZPositive()); - - List names = new ArrayList<>(); - List nlist = gc.getNames(); - if (nlist != null) - for (ThreddsMetadata.Vocab elem : nlist) { - names.add(elem.getText()); - } - this.geospatialCoverage.put("names", names); - } + } + + private void setCreators(Dataset ds, boolean isLocalCatalog) { + java.util.List creators = ds.getCreators(); + this.creators = new ArrayList<>(creators.size()); + + for (ThreddsMetadata.Source t : creators) { + Map creatorMap = new HashMap<>(); + creatorMap.put("name", t.getName()); + creatorMap.put("email", t.getEmail()); + String href = t.getUrl(); + if (!isLocalCatalog) href = CatalogViewContextParser.makeHrefResolve(ds, href); + creatorMap.put("href", href); + this.creators.add(creatorMap); } - - private void setTimeCoverage(Dataset ds) { - DateRange tc = ds.getTimeCoverage(); - if (tc != null) { - this.timeCoverage = new HashMap<>(); - DateType start = tc.getStart(); - if (start != null) this.timeCoverage.put("start", start.toString()); - DateType end = tc.getEnd(); - if (end != null) this.timeCoverage.put("end", end.toString()); - TimeDuration duration = tc.getDuration(); - if (duration != null) this.timeCoverage.put("duration", duration.toString()); - TimeDuration resolution = tc.getResolution(); - if (resolution != null) this.timeCoverage.put("resolution", resolution.toString()); - } + } + + private void setPublishers(Dataset ds, boolean isLocalCatalog) { + this.publishers = new ArrayList<>(); + java.util.List publishers = ds.getPublishers(); + + for (ThreddsMetadata.Source t : publishers) { + Map pubMap = new HashMap<>(); + pubMap.put("name", t.getName()); + pubMap.put("email", t.getEmail()); + String href = t.getUrl(); + if (!isLocalCatalog) href = CatalogViewContextParser.makeHrefResolve(ds, href); + pubMap.put("href", href); + this.publishers.add(pubMap); } - - private void setMetadata(Dataset ds, boolean isLocalCatalog) { - java.util.List metadata = ds.getMetadataOther(); - this.metadata = new ArrayList<>(metadata.size()); - - for (ThreddsMetadata.MetadataOther m : metadata) { - Map metadataMap = new HashMap<>(); - if (m.getXlinkHref() != null) { - String type = (m.getType() == null) ? "" : m.getType(); - metadataMap.put("title", (m.getTitle() == null) ? "Type " + type : m.getTitle()); - String mdLink = m.getXlinkHref(); - if (!isLocalCatalog) mdLink = CatalogViewContextParser.makeHrefResolve(ds, mdLink); - metadataMap.put("href", mdLink); - } - } + } + + private void setVariables(Dataset ds, boolean isLocalCatalog) { + List vars = ds.getVariables(); + this.variables = new ArrayList<>(vars.size()); + + for (ThreddsMetadata.VariableGroup t : vars) { + Map varGroup = new HashMap(); + String vocab = t.getVocabulary(); + varGroup.put("title", vocab); + ThreddsMetadata.UriResolved vocabUri = t.getVocabUri(); + if (vocabUri != null) { + varGroup.put("href", isLocalCatalog ? vocabUri.href : vocabUri.resolved.toString()); + } + + List> varList = new ArrayList<>(); + List vlist = t.getVariableList(); + for (ThreddsMetadata.Variable v : vlist) { + Map var= new HashMap<>(); + String units = (v.getUnits() == null || v.getUnits().length() == 0) ? "" : " (" + v.getUnits() + ") "; + var.put("nameAndUnits", v.getName() + units); + var.put("description", v.getDescription()); + var.put("vocabularyName", v.getVocabularyName()); + varList.add(var); + } + varGroup.put("varList", varList); + this.variables.add(varGroup); } - private void setProperties(Dataset ds, boolean isLocalCatalog) { - java.util.List propsOrg = ds.getProperties(); - java.util.List props = new ArrayList<>(ds.getProperties().size()); - for (Property p : propsOrg) { - if (!p.getName().startsWith("viewer")) // eliminate the viewer properties from the html view - props.add(p); - } - - this.properties = new ArrayList<>(props.size()); - for (Property p : props) { - Map propsMap = new HashMap<>(); - if (p.getName().equals("attachments")) { // LOOK whats this ? - propsMap.put("href", !isLocalCatalog ? CatalogViewContextParser.makeHrefResolve(ds, p.getValue()) : p.getValue()); - } - propsMap.put("name", p.getName()); - propsMap.put("value", p.getValue()); + // LOOK what about VariableMapLink string ?? + ThreddsMetadata.UriResolved uri = ds.getVariableMapLink(); + if (uri != null) { + this.variableMapLink = uri.resolved.toASCIIString(); + } + } + + private void setGeospatialCoverage(Dataset ds) { + ThreddsMetadata.GeospatialCoverage gc = ds.getGeospatialCoverage(); + this.geospatialCoverage = new HashMap<>(); + if (gc != null) { + this.geospatialCoverage.put("eastWestRange", rangeString(gc.getEastWestRange())); + this.geospatialCoverage.put("northSouthRange", rangeString(gc.getNorthSouthRange())); + ThreddsMetadata.GeospatialRange r = gc.getUpDownRange(); + if (r != null && r.getSize() > 0) { + this.geospatialCoverage.put("upDownRange", rangeString(r)); + this.geospatialCoverage.put("zPositive", gc.getZPositive()); + } + + List names = new ArrayList<>(); + List nlist = gc.getNames(); + if (nlist != null) + for (ThreddsMetadata.Vocab elem : nlist) { + names.add(elem.getText()); } + this.geospatialCoverage.put("names", names); } - - private String rangeString(ThreddsMetadata.GeospatialRange r) { - if (r == null) return ""; - String units = (r.getUnits() == null) ? "" : " " + r.getUnits(); - String resolution = r.hasResolution() ? " Resolution=" + r.getResolution() : ""; - return r.getStart() + " to " + (r.getStart() + r.getSize()) + resolution + units; + } + + private void setTimeCoverage(Dataset ds) { + DateRange tc = ds.getTimeCoverage(); + this.timeCoverage = new HashMap<>(); + if (tc != null) { + DateType start = tc.getStart(); + if (start != null) this.timeCoverage.put("start", start.toString()); + DateType end = tc.getEnd(); + if (end != null) this.timeCoverage.put("end", end.toString()); + TimeDuration duration = tc.getDuration(); + if (duration != null) this.timeCoverage.put("duration", duration.toString()); + TimeDuration resolution = tc.getResolution(); + if (resolution != null) this.timeCoverage.put("resolution", resolution.toString()); + } + } + + private void setMetadata(Dataset ds, boolean isLocalCatalog) { + java.util.List metadata = ds.getMetadataOther(); + this.metadata = new ArrayList<>(metadata.size()); + + for (ThreddsMetadata.MetadataOther m : metadata) { + Map metadataMap = new HashMap<>(); + if (m.getXlinkHref() != null) { + String type = (m.getType() == null) ? "" : m.getType(); + metadataMap.put("title", (m.getTitle() == null) ? "Type " + type : m.getTitle()); + String mdLink = m.getXlinkHref(); + if (!isLocalCatalog) mdLink = CatalogViewContextParser.makeHrefResolve(ds, mdLink); + metadataMap.put("href", mdLink); + } + } + } + + private void setProperties(Dataset ds, boolean isLocalCatalog) { + java.util.List propsOrg = ds.getProperties(); + java.util.List props = new ArrayList<>(ds.getProperties().size()); + for (Property p : propsOrg) { + if (!p.getName().startsWith("viewer")) // eliminate the viewer properties from the html view + props.add(p); } - private String makeHrefResolve(Dataset ds, String href) { - Catalog cat = ds.getParentCatalog(); - if (cat != null) { - try { - java.net.URI uri = cat.resolveUri(href); - href = uri.toString(); - } catch (java.net.URISyntaxException e) { - return "DatasetHtmlWriter: error parsing URL= " + href; - } - } - return href; + this.properties = new ArrayList<>(props.size()); + for (Property p : props) { + Map propsMap = new HashMap<>(); + if (p.getName().equals("attachments")) { // LOOK whats this ? + propsMap.put("href", !isLocalCatalog ? CatalogViewContextParser.makeHrefResolve(ds, p.getValue()) : p.getValue()); + } + propsMap.put("name", p.getName()); + propsMap.put("value", p.getValue()); + this.properties.add(propsMap); + } + } + + private String rangeString(ThreddsMetadata.GeospatialRange r) { + if (r == null) return ""; + String units = (r.getUnits() == null) ? "" : " " + r.getUnits(); + String resolution = r.hasResolution() ? " Resolution=" + r.getResolution() : ""; + return r.getStart() + " to " + (r.getStart() + r.getSize()) + resolution + units; + } + + private String makeHrefResolve(Dataset ds, String href) { + Catalog cat = ds.getParentCatalog(); + if (cat != null) { + try { + java.net.URI uri = cat.resolveUri(href); + href = uri.toString(); + } catch (java.net.URISyntaxException e) { + return "CatalogViewContextParser: error parsing URL= " + href; + } } + return href; + } - public String getName() { return this.name; } + public String getName() { return this.name; } - public String getCatUrl() { return this.catUrl; } + public String getCatUrl() { return this.catUrl; } - public List> getAccess() { return this.access; } + public List> getDocumentation() { return this.documentation; } - public List> getContributors() { return this.contributors; } + public List> getAccess() { return this.access; } - public List> getKeywords() { return this.keywords; } + public List> getContributors() { return this.contributors; } - public List> getDates() { return this.dates; } + public List> getKeywords() { return this.keywords; } - public List> getProjects() { return this.projects; } + public List> getDates() { return this.dates; } - public List> getCreators() { return this.creators; } + public List> getProjects() { return this.projects; } - public List> getPublishers() { return this.publishers; } + public List> getCreators() { return this.creators; } - public List> getVariables() { return this.variables; } + public List> getPublishers() { return this.publishers; } - public String getVariableMapLink() { return this.variableMapLink; } + public List> getVariables() { return this.variables; } - public Map getGeospatialCoverage() { return this.geospatialCoverage;} + public String getVariableMapLink() { return this.variableMapLink; } - public Map getTimeCoverage() { return this.timeCoverage; } + public Map getGeospatialCoverage() { return this.geospatialCoverage;} - public List> getMetadata() { return this.metadata; } + public Map getTimeCoverage() { return this.timeCoverage; } - public List> getProperties() { return this.properties; } + public List> getMetadata() { return this.metadata; } - public Map getAllContext() { return this.context; } + public List> getProperties() { return this.properties; } - public Object getContextItem(String key) { return this.context.get(key); } + public Map getAllContext() { return this.context; } - public void addContextItem(String key, Object value) { this.context.put(key, value); } + public Object getContextItem(String key) { return this.context.get(key); } + + public void addContextItem(String key, Object value) { this.context.put(key, value); } + + public List> getViewerLinks() { return this.viewerLinks; } + + public void setViewers(Dataset ds, List viewerLinks) { + for (ViewerLinkProvider.ViewerLink viewer : viewerLinks) { + Map viewerMap = new HashMap<>(); + viewerMap.put("title", viewer.getTitle()); + viewerMap.put("href", viewer.getUrl()); + this.viewerLinks.add(viewerMap); + } + } } diff --git a/tds/src/main/java/thredds/server/catalogservice/RemoteCatalogServiceController.java b/tds/src/main/java/thredds/server/catalogservice/RemoteCatalogServiceController.java index 254734f1de..53176f3f55 100644 --- a/tds/src/main/java/thredds/server/catalogservice/RemoteCatalogServiceController.java +++ b/tds/src/main/java/thredds/server/catalogservice/RemoteCatalogServiceController.java @@ -20,7 +20,6 @@ import thredds.client.catalog.Dataset; import thredds.client.catalog.builder.CatalogBuilder; import thredds.core.AllowedServices; -import thredds.core.ConfigCatalogHtmlWriter; import thredds.core.StandardService; import thredds.server.config.HtmlConfigBean; import thredds.server.exception.ServiceNotAllowed; @@ -51,9 +50,6 @@ public class RemoteCatalogServiceController { @Autowired private HtmlConfigBean htmlConfig; - @Autowired - private ConfigCatalogHtmlWriter writer; - @Autowired private CatalogViewContextParser parser; @@ -92,9 +88,9 @@ protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResp /////////////////////////////////////////// // Otherwise, handle catalog as indicated by "command". - switch (params.getCommand()) { + switch (params.getCommand()) { case SHOW: - return new ModelAndView("templates/catalog", parser.getCatalogViewContext(catalog, false)); + return new ModelAndView("templates/catalog", parser.getCatalogViewContext(catalog, false)); case SUBSET: String datasetId = params.getDataset(); @@ -107,7 +103,7 @@ protected ModelAndView handleRequest(HttpServletRequest request, HttpServletResp } if (params.isHtmlView()) { - return new ModelAndView("templates/dataset", parser.getDatasetViewContext(dataset, false)); + return new ModelAndView("templates/dataset", parser.getDatasetViewContext(dataset, request, false)); } else { Catalog subsetCat = catalog.subsetCatalogOnDataset(dataset); return new ModelAndView("threddsInvCatXmlView", "catalog", subsetCat); diff --git a/tds/src/main/java/thredds/server/viewer/Viewer.java b/tds/src/main/java/thredds/server/viewer/Viewer.java index 97e550c56e..5d5ccd552e 100644 --- a/tds/src/main/java/thredds/server/viewer/Viewer.java +++ b/tds/src/main/java/thredds/server/viewer/Viewer.java @@ -17,13 +17,12 @@ * */ public interface Viewer { - /** * Is this dataset vieweable by me? * @param ds the dataset * @return true if viewable */ - boolean isViewable( Dataset ds); + boolean isViewable( Dataset ds); /** * Get an HTML fragment link to the viewer JNLP file, for this dataset. @@ -34,6 +33,13 @@ public interface Viewer { * @param req the request * @return HTML fragment string */ - String getViewerLinkHtml( Dataset ds, HttpServletRequest req); + String getViewerLinkHtml( Dataset ds, HttpServletRequest req); + + /** + ** @param ds the dataset to view + * @param req the request + * @return HTML fragment string + */ + ViewerLinkProvider.ViewerLink getViewerLink(Dataset ds, HttpServletRequest req); } diff --git a/tds/src/main/java/thredds/server/viewer/ViewerService.java b/tds/src/main/java/thredds/server/viewer/ViewerService.java index 80d974d519..d1c288ff6b 100644 --- a/tds/src/main/java/thredds/server/viewer/ViewerService.java +++ b/tds/src/main/java/thredds/server/viewer/ViewerService.java @@ -22,5 +22,7 @@ public interface ViewerService { boolean registerViewer(Viewer v); void showViewers(Formatter sbuff, Dataset dataset, HttpServletRequest req); + + List getViewerLinks(Dataset dataset, HttpServletRequest req); } diff --git a/tds/src/main/java/thredds/server/viewer/ViewerServiceImpl.java b/tds/src/main/java/thredds/server/viewer/ViewerServiceImpl.java index 72a3688e86..1c707de7d1 100644 --- a/tds/src/main/java/thredds/server/viewer/ViewerServiceImpl.java +++ b/tds/src/main/java/thredds/server/viewer/ViewerServiceImpl.java @@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletRequest; import com.coverity.security.Escape; +import opendap.util.Tools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -103,6 +104,22 @@ public void showViewers(Formatter out, Dataset dataset, HttpServletRequest req) out.format("\r\n"); } + @Override + public List getViewerLinks(Dataset dataset, HttpServletRequest req) { + List viewerLinks = new ArrayList<>(); + + for (Viewer viewer : viewers) { + if (viewer.isViewable(dataset)) { + if (viewer instanceof ViewerLinkProvider) { + viewerLinks.addAll(((ViewerLinkProvider) viewer).getViewerLinks(dataset, req)); + } else { + viewerLinks.add(viewer.getViewerLink(dataset, req)); + } + } + } + return viewerLinks; + } + @SuppressWarnings("unused") @PostConstruct private void registerViewers() { @@ -115,6 +132,7 @@ private void registerViewers() { // Viewers... // ToolsUI private static class ToolsUI implements Viewer { + private static final String title = "NetCDF-Java toolUi (webstart)"; public boolean isViewable(Dataset ds) { String id = ds.getID(); @@ -122,18 +140,27 @@ public boolean isViewable(Dataset ds) { } public String getViewerLinkHtml(Dataset ds, HttpServletRequest req) { + ViewerLinkProvider.ViewerLink viewerLink = this.getViewerLink(ds, req); + Formatter query = new Formatter(); + query.format("%s", viewerLink.getUrl(), viewerLink.getTitle()); + return query.toString(); + } + + @Override + public ViewerLinkProvider.ViewerLink getViewerLink(Dataset ds, HttpServletRequest req) { String base = ds.getParentCatalog().getUriString(); if (base.endsWith(".html")) base = base.substring(0, base.length() - 5) + ".xml"; Formatter query = new Formatter(); - query.format("NetCDF-Java ToolsUI (webstart)", base, ds.getID()); - return query.toString(); + query.format("%s/view/ToolsUI.jnlp?", req.getContextPath()); + query.format("catalog=%s&dataset=%s", base, ds.getID()); + return new ViewerLinkProvider.ViewerLink(ToolsUI.title, query.toString()); } } // IDV private static class IDV implements Viewer { + private static final String title = "Integrated Data Viewer (IDV) (webstart)"; public boolean isViewable(Dataset ds) { Access access = getOpendapAccess(ds); @@ -145,6 +172,13 @@ public boolean isViewable(Dataset ds) { } public String getViewerLinkHtml(Dataset ds, HttpServletRequest req) { + ViewerLinkProvider.ViewerLink viewerLink = this.getViewerLink(ds, req); + + return "" + viewerLink.getTitle() + ""; + } + + @Override + public ViewerLinkProvider.ViewerLink getViewerLink(Dataset ds, HttpServletRequest req) { Access access = getOpendapAccess(ds); if (access == null) return null; @@ -163,10 +197,9 @@ public String getViewerLinkHtml(Dataset ds, HttpServletRequest req) { logger.error("Resolve URL with " + req.getRequestURL(), e); } } - - return "Integrated Data Viewer (IDV) (webstart)"; + String url = req.getContextPath() + "/view/idv.jnlp?url=" + + dataURI.toString(); + return new ViewerLinkProvider.ViewerLink(IDV.title, url); } private Access getOpendapAccess(Dataset ds) { @@ -179,6 +212,7 @@ private Access getOpendapAccess(Dataset ds) { // LOOK whats this for ?? private static final String propertyNamePrefix = "viewer"; + private static class StaticView implements ViewerLinkProvider { public boolean isViewable(Dataset ds) { @@ -193,6 +227,14 @@ public String getViewerLinkHtml(Dataset ds, HttpServletRequest req) { return "" + firstLink.getTitle() + ""; } + @Override + public ViewerLink getViewerLink(Dataset ds, HttpServletRequest req) { + List viewerLinks = getViewerLinks(ds, req); + if (viewerLinks.isEmpty()) + return null; + return viewerLinks.get(0); + } + @Override public List getViewerLinks(Dataset ds, HttpServletRequest req) { List viewerProperties = findViewerProperties(ds); diff --git a/tds/src/main/java/thredds/server/wms/Godiva3Viewer.java b/tds/src/main/java/thredds/server/wms/Godiva3Viewer.java index 5b7ac2c482..36bd33478f 100644 --- a/tds/src/main/java/thredds/server/wms/Godiva3Viewer.java +++ b/tds/src/main/java/thredds/server/wms/Godiva3Viewer.java @@ -39,46 +39,54 @@ import thredds.client.catalog.ServiceType; import thredds.server.config.ThreddsConfig; import thredds.server.viewer.Viewer; +import thredds.server.viewer.ViewerLinkProvider; /** * A Viewer for viewing datasets using the built-in Godiva3 client. The viewer * must be configured in {@code ${tomcat_home}/content/thredds/threddsConfig.xml}, as per - * instructions here(needs updated). + * instructions here(needs updated). * * @author Jon */ public class Godiva3Viewer implements Viewer { - static private final Logger logger = LoggerFactory.getLogger(Godiva3Viewer.class); + static private final Logger logger = LoggerFactory.getLogger(Godiva3Viewer.class); - /** - * Returns true if this is a gridded dataset that is accessible via WMS. - */ - @Override - public boolean isViewable(Dataset ds) - { - Access access = ds.getAccess(ServiceType.WMS); - return access != null && (ThreddsConfig.getBoolean("WMS.allow", false)); - } + static private final String title = "Godiva3 (browser-based)"; + + /** + * Returns true if this is a gridded dataset that is accessible via WMS. + */ + @Override + public boolean isViewable(Dataset ds) { + Access access = ds.getAccess(ServiceType.WMS); + return access != null && (ThreddsConfig.getBoolean("WMS.allow", false)); + } - @Override - public String getViewerLinkHtml(Dataset ds, HttpServletRequest req) - { - Access access = ds.getAccess(ServiceType.WMS); - if (access == null) return null; + @Override + public String getViewerLinkHtml(Dataset ds, HttpServletRequest req) { + ViewerLinkProvider.ViewerLink viewerLink = getViewerLink(ds, req); + return "" + viewerLink.getTitle() + ""; + } - URI dataURI = access.getStandardUri(); - if (dataURI == null) { - logger.warn("Godiva3Viewer access URL failed on {}", ds.getName()); - return null; - } + @Override + public ViewerLinkProvider.ViewerLink getViewerLink(Dataset ds, HttpServletRequest req) { + Access access = ds.getAccess(ServiceType.WMS); + if (access == null) return null; + + URI dataURI = access.getStandardUri(); + if (dataURI == null) { + logger.warn("Godiva3Viewer access URL failed on {}", ds.getName()); + return null; + } - try { - URI base = new URI( req.getRequestURL().toString()); - dataURI = base.resolve( dataURI); + try { + URI base = new URI(req.getRequestURL().toString()); + dataURI = base.resolve(dataURI); - } catch (URISyntaxException e) { - logger.warn("Godiva3Viewer URL=" + req.getRequestURL().toString(), e); - return null; - } - return "Godiva3 (browser-based)"; + } catch (URISyntaxException e) { + logger.warn("Godiva3Viewer URL=" + req.getRequestURL().toString(), e); + return null; } + String url = req.getContextPath() + "/Godiva.html?server=" + dataURI.toString(); + return new ViewerLinkProvider.ViewerLink(Godiva3Viewer.title, url); + } } diff --git a/tds/src/main/webapp/WEB-INF/templates/catalog.html b/tds/src/main/webapp/WEB-INF/templates/catalog.html index 9242eb17cd..11fac9b5ac 100644 --- a/tds/src/main/webapp/WEB-INF/templates/catalog.html +++ b/tds/src/main/webapp/WEB-INF/templates/catalog.html @@ -5,8 +5,17 @@ TDS Catalog - + diff --git a/tds/src/main/webapp/WEB-INF/templates/catalogFragments.html b/tds/src/main/webapp/WEB-INF/templates/catalogFragments.html index f688e46b1c..8ef59ccaa0 100644 --- a/tds/src/main/webapp/WEB-INF/templates/catalogFragments.html +++ b/tds/src/main/webapp/WEB-INF/templates/catalogFragments.html @@ -19,7 +19,7 @@   -- - + diff --git a/tds/src/main/webapp/WEB-INF/templates/dataset.html b/tds/src/main/webapp/WEB-INF/templates/dataset.html index 65dce3f44d..d95eda49fe 100644 --- a/tds/src/main/webapp/WEB-INF/templates/dataset.html +++ b/tds/src/main/webapp/WEB-INF/templates/dataset.html @@ -10,12 +10,14 @@ - + + +

THREDDS-DEV Data Server

-

THREDDS Data Server

+

THREDDS Data Server

@@ -23,124 +25,34 @@

THREDDS Data Serv

-
-
    -
  • -
-
- -
-

Documentation:

-
    -
  • -
  • -
-
- -
-

Access:

-
    -
  1. -
-
- -
-

Contributors:

-
    -
  • -
-
- -
-

Keywords:

-
    -
  • -
-
- -
-

Dates:

-
    -
  • -
-
- -
-

Projects:

-
    -
  • -
-
- -
-

Creators:

-
    -
  • -
      -
    • -
    • -
    -
  • -
-
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
-
-

Publishers:

-
    -
  • -
      -
    • -
    • -
    -
  • -
-
- -
-

Variables:

- -
- -
-

GeospatialCoverage:

-
    -
  • -
  • -
  • -
-
- -
-

TimeCoverage:

-
    -
  • -
  • -
  • -
  • -
-
- -
-

Properties:

-
    -
  • -
  • -
-
- -

Viewers:

+
+ +
+ +
+ +
+ +
+ +
+ \ No newline at end of file diff --git a/tds/src/main/webapp/WEB-INF/templates/datasetFragments.html b/tds/src/main/webapp/WEB-INF/templates/datasetFragments.html new file mode 100644 index 0000000000..61122b45f5 --- /dev/null +++ b/tds/src/main/webapp/WEB-INF/templates/datasetFragments.html @@ -0,0 +1,170 @@ + + + + + + + +
+
    +
  • + +
  • +
+
+ +
+

Documentation:

+
    +
  • + + +
  • +
  • + + +
  • +
+
+ +
+

Access:

+
    +
  1. + + +
  2. +
+
+ +
+

Contributors:

+
    +
  • + + +
  • +
+
+ +
+

Keywords:

+
    +
  • + + +
  • +
+
+ +
+

Dates:

+
    +
  • + + +
  • +
+
+ +
+

Projects:

+
    +
  • + + +
  • +
+
+ +
+

Creators:

+
    +
  • + +
      +
    • +
    • +
    +
  • +
+
+ +
+

Publishers:

+
    +
  • + +
      +
    • +
    • +
    +
  • +
+
+ +
+

Variables:

+
    +
  • Vocabulary + + +
      +
    • + + + +
    • +
    +
  • +
+
+

Variables:

+
  • + +
+
+
+ +
+

GeospatialCoverage:

+
    +
  • Longitude:
  • +
  • Latitude:
  • +
  • + Altitude: +
  • +
+
+ +
+

TimeCoverage:

+
    +
  • Start:
  • +
  • End: +
  • Duration: +
  • Resolution: +
+
+ +
+

Properties:

+
    +
  • +
  • +
  • +
+
+ +
+

Viewers:

+
    +
  • + +
  • +
+
+ + + \ No newline at end of file From 74d9b9e8a43975cf8c2785c27a1b4c4625b81aa0 Mon Sep 17 00:00:00 2001 From: haileyajohnson Date: Mon, 18 Jun 2018 11:26:31 -0600 Subject: [PATCH 4/5] add standard header/footer; separate ncss and common fragments --- .../CatalogViewContextParser.java | 34 +++-- .../webapp/WEB-INF/templates/catalog.html | 14 +- .../WEB-INF/templates/commonFragments.html | 115 ++------------- .../webapp/WEB-INF/templates/dataset.html | 14 +- .../WEB-INF/templates/ncssFragments.html | 138 ++++++++++++++++++ .../webapp/WEB-INF/templates/ncssGrid.html | 18 +-- .../WEB-INF/templates/ncssGridAsPoint.html | 16 +- .../webapp/WEB-INF/templates/ncssPoint.html | 16 +- .../webapp/WEB-INF/templates/ncssStation.html | 18 +-- tds/src/main/webapp/tds.css | 26 ++++ 10 files changed, 237 insertions(+), 172 deletions(-) create mode 100644 tds/src/main/webapp/WEB-INF/templates/ncssFragments.html diff --git a/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java b/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java index 4adfd56c5e..b43746f0e9 100644 --- a/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java +++ b/tds/src/main/java/thredds/server/catalogservice/CatalogViewContextParser.java @@ -39,13 +39,7 @@ public class CatalogViewContextParser { public Map getCatalogViewContext(Catalog cat, boolean isLocalCatalog) { Map model = new HashMap<>(); - String googleTrackingCode = htmlConfig.getGoogleTrackingCode(); - if (googleTrackingCode.isEmpty()) googleTrackingCode = null; - model.put("googleTracking", googleTrackingCode); - - model.put("serverName", serverInfo.getName()); - model.put("logoUrl", serverInfo.getLogoUrl()); - model.put("logoAlt", serverInfo.getLogoAltText()); + addBaseContext(model); List catalogItems = new ArrayList<>(); addCatalogItems(cat, catalogItems, isLocalCatalog, 0); @@ -56,8 +50,20 @@ public Map getCatalogViewContext(Catalog cat, boolean isLocalCat public Map getDatasetViewContext(Dataset ds, HttpServletRequest req, boolean isLocalCatalog) { Map model = new HashMap<>(); + addBaseContext(model); - model.put("googleTracking", htmlConfig.getGoogleTrackingCode()); + DatasetContext context = new DatasetContext(ds, isLocalCatalog); + populateDatasetContext(ds, context, req, isLocalCatalog); + + model.put("dataset", context); + + return model; + } + + private void addBaseContext(Map model) { + String googleTrackingCode = htmlConfig.getGoogleTrackingCode(); + if (googleTrackingCode.isEmpty()) googleTrackingCode = null; + model.put("googleTracking", googleTrackingCode); model.put("serverName", serverInfo.getName()); model.put("logoUrl", serverInfo.getLogoUrl()); model.put("logoAlt", serverInfo.getLogoAltText()); @@ -65,13 +71,11 @@ public Map getDatasetViewContext(Dataset ds, HttpServletRequest model.put("installUrl", htmlConfig.getInstallUrl()); model.put("webappName", htmlConfig.getWebappName()); model.put("webappUrl", htmlConfig.getWebappUrl()); - - DatasetContext context = new DatasetContext(ds, isLocalCatalog); - populateDatasetContext(ds, context, req, isLocalCatalog); - - model.put("dataset", context); - - return model; + model.put("webappVersion", htmlConfig.getWebappVersion()); + model.put("webappBuildTimestamp", htmlConfig.getWebappVersionBuildDate()); + model.put("webbappDocsUrl", htmlConfig.getWebappDocsUrl()); + model.put("hostInst", htmlConfig.getHostInstName()); + model.put("hostInstUrl", htmlConfig.getHostInstUrl()); } protected void addCatalogItems(DatasetNode cat, List catalogItems, boolean isLocalCatalog, int level) diff --git a/tds/src/main/webapp/WEB-INF/templates/catalog.html b/tds/src/main/webapp/WEB-INF/templates/catalog.html index 11fac9b5ac..0bc6c39406 100644 --- a/tds/src/main/webapp/WEB-INF/templates/catalog.html +++ b/tds/src/main/webapp/WEB-INF/templates/catalog.html @@ -4,7 +4,7 @@ TDS Catalog - + @@ -13,7 +15,7 @@ -
+

@@ -46,7 +48,7 @@

-
+
\ No newline at end of file