thredds.client.catalog.tools.DatasetHtmlWriter Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
* See LICENSE for license information.
*/
package thredds.client.catalog.tools;
import com.google.common.escape.Escaper;
import com.google.common.html.HtmlEscapers;
import com.google.common.net.UrlEscapers;
import thredds.client.catalog.*;
import ucar.nc2.units.DateRange;
import ucar.nc2.units.DateType;
import ucar.nc2.units.TimeDuration;
import ucar.unidata.util.Format;
import java.util.ArrayList;
import java.util.Formatter;
/**
* Create Html from a dataset
*
* @author caron
* @since 1/8/2015
*/
public class DatasetHtmlWriter {
private Escaper htmlEscaper = HtmlEscapers.htmlEscaper();
private Escaper urlPathEscaper = UrlEscapers.urlPathSegmentEscaper();
private Escaper urlParamEscaper = UrlEscapers.urlFormParameterEscaper();
/**
* Write an Html representation of the given dataset.
* With datasetEvents, catrefEvents = true, this is used to construct an HTML page on the client
* (eg using HtmlPage); the client then detects URL clicks and processes.
*
With datasetEvents, catrefEvents = false, this is used to construct an HTML page on the server.
* (eg using HtmlPage); the client then detects URL clicks and processes.
*
* @param out put HTML here.
* @param ds the dataset.
* @param complete if true, add HTML header and ender so its a complete, valid HTML page.
* @param isServer if true, then we are in the thredds data server, so do the following:
* - append "html" to DODS Access URLs
*
* @param datasetEvents if true, prepend "dataset:" to any dataset access URLS
* @param catrefEvents if true, prepend "catref:" to any catref URLS
*/
public void writeHtmlDescription(Formatter out, Dataset ds,
boolean complete, boolean isServer,
boolean datasetEvents, boolean catrefEvents,
boolean resolveRelativeUrls) {
if (ds == null) return;
if (complete) {
out.format("%n");
out.format("%n");
out.format("%n");
out.format("%n");
out.format("%n");
out.format("%n");
}
out.format("Dataset: %s
%n", ds.getName());
if (ds.getDataFormatName() != null)
out.format(" - Data format: %s
%n", htmlEscaper.escape(ds.getDataFormatName()));
if ((ds.getDataSize() > 0))
out.format(" - Data size: %s
%n", Format.formatByteSize(ds.getDataSize()));
if (ds.getFeatureTypeName() != null)
out.format(" - Feature type: %s
%n", htmlEscaper.escape(ds.getFeatureTypeName()));
if (ds.getCollectionType() != null)
out.format(" - Collection type: %s
%n", htmlEscaper.escape(ds.getCollectionType()));
if (ds.isHarvest())
out.format(" - Harvest: true
%n");
if (ds.getAuthority() != null)
out.format(" - Naming Authority: %s
%n%n", htmlEscaper.escape(ds.getAuthority()));
if (ds.getId() != null)
out.format(" - ID: %s
%n", htmlEscaper.escape(ds.getId()));
if (ds.getRestrictAccess() != null)
out.format(" - RestrictAccess: %s
%n", htmlEscaper.escape(ds.getRestrictAccess()));
if (ds instanceof CatalogRef) {
CatalogRef catref = (CatalogRef) ds;
String href = resolveRelativeUrls | catrefEvents ? resolve(ds, catref.getXlinkHref()) : catref.getXlinkHref();
if (catrefEvents) href = "catref:" + href;
out.format(" - CatalogRef: %s
%n", makeHref(href, null, null));
}
out.format("
%n");
java.util.List docs = ds.getDocumentation();
if (docs.size() > 0) {
out.format("Documentation:
%n%n");
for (Documentation doc : docs) {
String type = (doc.getType() == null) ? "" : "" + htmlEscaper.escape(doc.getType()) + ": ";
String inline = doc.getInlineContent();
if ((inline != null) && (inline.length() > 0))
out.format(" - %s %s
%n", type, htmlEscaper.escape(inline));
if (doc.hasXlink()) {
out.format(" - %s %s
%n", type, makeHref(doc.getXlinkHref(), null, doc.getXlinkTitle()));
}
}
out.format("
%n");
}
java.util.List access = ds.getAccess();
if (access.size() > 0) {
out.format("Access:
%n%n");
for (Access a : access) {
Service s = a.getService();
String urlString = resolveRelativeUrls || datasetEvents ? a.getStandardUrlName() : a.getUnresolvedUrlName();
String queryString = null;
// String fullUrlString = urlString;
if (datasetEvents) urlString = "dataset:" + urlString;
ServiceType stype = s.getType();
if (isServer && 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('#'));
/* try {
catalogUrl = URLEncoder.encode(catalogUrl, "UTF-8");
datasetId = URLEncoder.encode(datasetId, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} */
queryString = "catalog=" + urlParamEscaper.escape(catalogUrl) + "&dataset=" + urlParamEscaper.escape(datasetId);
}
break;
case NetcdfSubset:
urlString = urlString + "/dataset.html";
break;
case CdmRemote:
queryString = "req=cdl";
break;
case CdmrFeature:
queryString = "req=form";
}
out.format(" - %s: %s
%n", s.getServiceTypeName(), makeHref(urlString, queryString, null));
}
out.format("
%n");
}
java.util.List contributors = ds.getContributors();
if (contributors.size() > 0) {
out.format("Contributors:
%n%n");
for (ThreddsMetadata.Contributor t : contributors) {
String role = (t.getRole() == null) ? "" : " (" + htmlEscaper.escape(t.getRole()) + ") ";
out.format(" - %s %s
%n", htmlEscaper.escape(t.getName()), role);
}
out.format("
%n");
}
java.util.List keywords = ds.getKeywords();
if (keywords.size() > 0) {
out.format("Keywords:
%n%n");
for (ThreddsMetadata.Vocab t : keywords) {
String vocab = (t.getVocabulary() == null) ? "" : " (" + htmlEscaper.escape(t.getVocabulary()) + ") ";
out.format(" - %s %s
%n", htmlEscaper.escape(t.getText()), vocab);
}
out.format("
%n");
}
java.util.List dates = ds.getDates();
if (dates.size() > 0) {
out.format("Dates:
%n%n");
for (DateType d : dates) {
String type = (d.getType() == null) ? "" : " (" + htmlEscaper.escape(d.getType()) + ") ";
out.format(" - %s %s
%n", htmlEscaper.escape(d.getText()), type);
}
out.format("
%n");
}
java.util.List projects = ds.getProjects();
if (projects.size() > 0) {
out.format("Projects:
%n%n");
for (ThreddsMetadata.Vocab t : projects) {
String vocab = (t.getVocabulary() == null) ? "" : " (" + htmlEscaper.escape(t.getVocabulary()) + ") ";
out.format(" - %s %s
%n", htmlEscaper.escape(t.getText()), vocab);
}
out.format("
%n");
}
java.util.List creators = ds.getCreators();
if (creators.size() > 0) {
out.format("Creators:
%n%n");
for (ThreddsMetadata.Source t : creators) {
out.format(" - %s
%n", htmlEscaper.escape(t.getName()));
out.format(" - email: %s
%n", htmlEscaper.escape(t.getEmail()));
if (t.getUrl() != null) {
String newUrl = resolveRelativeUrls ? makeHrefResolve(ds, t.getUrl(), null) : makeHref(t.getUrl(), null, null);
out.format(" - %s
%n", newUrl);
}
out.format("
%n");
}
out.format("
%n");
}
java.util.List publishers = ds.getPublishers();
if (publishers.size() > 0) {
out.format("Publishers:
%n%n");
for (ThreddsMetadata.Source t : publishers) {
out.format(" - %s
%n", htmlEscaper.escape(t.getName()));
out.format(" - email: %s%n", htmlEscaper.escape(t.getEmail()));
if (t.getUrl() != null) {
String urlLink = resolveRelativeUrls ? makeHrefResolve(ds, t.getUrl(), null) : makeHref(t.getUrl(), null, null);
out.format("
- %s
%n", urlLink);
}
out.format("
%n");
}
out.format("
%n");
}
/*
4.2:
Variables:
- Vocabulary [DIF]:
- Reflectivity = = EARTH SCIENCE > Spectral/Engineering > Radar > Radar Reflectivity (db)
- Velocity = = EARTH SCIENCE > Spectral/Engineering > Radar > Doppler Velocity (m/s)
- SpectrumWidth = = EARTH SCIENCE > Spectral/Engineering > Radar > Doppler Spectrum Width (m/s)
4.3:
Variables:
- Vocabulary [CF-1.0]:
- d3d (meters) = 3D Depth at Nodes
= depth_at_nodes
- depth (meters) = Bathymetry = depth
- eta (m) = =
- temp (Celsius) = Temperature
= sea_water_temperature
- u (m/s) = Eastward Water
Velocity
= eastward_sea_water_velocity
- v (m/s) = Northward Water
Velocity
= northward_sea_water_velocity
*/
java.util.List vars = ds.getVariables();
if (vars.size() > 0) {
out.format("Variables:
%n%n");
for (ThreddsMetadata.VariableGroup t : vars) {
out.format("- Vocabulary [");
if (t.getVocabUri() != null) {
ThreddsMetadata.UriResolved uri = t.getVocabUri();
String vocabLink = resolveRelativeUrls ? makeHref(uri.resolved.toString(), null, t.getVocabulary()) : makeHref(uri.href, null, t.getVocabulary());
out.format(vocabLink);
} else {
out.format(htmlEscaper.escape(t.getVocabulary()));
}
out.format("]:%n
%n");
java.util.List vlist = t.getVariableList();
if (vlist.size() > 0) {
for (ThreddsMetadata.Variable v : vlist) {
String units = (v.getUnits() == null || v.getUnits().length() == 0) ? "" : " (" + v.getUnits() + ") ";
out.format(" - %s = ", htmlEscaper.escape(v.getName() + units));
if (v.getDescription() != null)
out.format(" %s = ", htmlEscaper.escape(v.getDescription()));
if (v.getVocabularyName() != null)
out.format("%s", htmlEscaper.escape(v.getVocabularyName()));
out.format("%n");
}
}
out.format("
%n");
}
out.format("
%n");
}
// LOOK what about VariableMapLink string ??
if (ds.getVariableMapLink() != null) {
out.format("Variables:
%n");
ThreddsMetadata.UriResolved uri = ds.getVariableMapLink();
out.format("- %s
%n", makeHref(uri.resolved.toASCIIString(), null, "VariableMap"));
}
ThreddsMetadata.GeospatialCoverage gc = ds.getGeospatialCoverage();
if (gc != null) {
out.format("GeospatialCoverage:
%n%n");
// if (gc.isGlobal()) out.format(" - Global %n");
out.format("
- Longitude: %s
%n", rangeString(gc.getEastWestRange()));
out.format(" - Latitude: %s
%n", rangeString(gc.getNorthSouthRange()));
if (gc.getUpDownRange() != null) {
out.format(" - Altitude: %s (positive is %s)
%n", rangeString(gc.getUpDownRange()), gc.getZPositive());
}
java.util.List nlist = gc.getNames();
if ((nlist != null) && (nlist.size() > 0)) {
out.format(" - Names:
%n");
for (ThreddsMetadata.Vocab elem : nlist) {
out.format(" - %s
%n", htmlEscaper.escape(elem.getText()));
}
out.format("
%n");
}
out.format("
%n");
}
DateRange tc = ds.getTimeCoverage();
if (tc != null) {
out.format("TimeCoverage:
%n%n");
DateType start = tc.getStart();
if (start != null)
out.format(" - Start: %s
%n", start.toString());
DateType end = tc.getEnd();
if (end != null) {
out.format(" - End: %s
%n", end.toString());
}
TimeDuration duration = tc.getDuration();
if (duration != null)
out.format(" - Duration: %s
%n", htmlEscaper.escape(duration.toString()));
TimeDuration resolution = tc.getResolution();
if (resolution != null) {
out.format(" - Resolution: %s
%n", htmlEscaper.escape(resolution.toString()));
}
out.format("
%n");
}
java.util.List metadata = ds.getMetadataOther();
boolean gotSomeMetadata = false;
for (ThreddsMetadata.MetadataOther m : metadata) {
if (m.getXlinkHref() != null) gotSomeMetadata = true;
}
if (gotSomeMetadata) {
out.format("Metadata:
%n%n");
for (ThreddsMetadata.MetadataOther m : metadata) {
String type = (m.getType() == null) ? "" : m.getType();
if (m.getXlinkHref() != null) {
String title = (m.getTitle() == null) ? "Type " + type : m.getTitle();
String mdLink = resolveRelativeUrls ? makeHrefResolve(ds, m.getXlinkHref(), title) : makeHref(m.getXlinkHref(), null, title);
out.format(" - %s
%n", mdLink);
} //else {
//out.format(" -
"+m.getMetadataType()+" "+m.getContentObject()+"
%n");
//}
}
out.format("
%n");
}
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);
}
if (props.size() > 0) {
out.format("Properties:
%n%n");
for (Property p : props) {
if (p.getName().equals("attachments")) { // LOOK whats this ?
String attachLink = resolveRelativeUrls ? makeHrefResolve(ds, p.getValue(), p.getName()) : makeHref(p.getValue(), null, p.getName());
out.format(" - %s
%n", attachLink);
} else {
out.format(" - %s = \"%s\"
%n", htmlEscaper.escape(p.getName()), htmlEscaper.escape(p.getValue()));
}
}
out.format("
%n");
}
if (complete) out.format("");
}
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 htmlEscaper.escape(r.getStart() + " to " + (r.getStart() + r.getSize()) + resolution + units);
}
/**
* resolve reletive URLS against the catalog URL.
*
* @param ds use ds parent catalog, if it exists
* @param href URL to resolve
* @return resolved URL
*/
public String resolve(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;
}
private String makeHref(String urlPath, String query, String title) {
if (title == null) title = urlPath;
if (query != null)
urlPath += "?" + query;
return "" + htmlEscaper.escape(title) + "";
}
private String makeHrefResolve(Dataset ds, String href, String title) {
href = resolve(ds, href);
return makeHref(href, null, title);
}
}