Merge pull request #121 from geosolutions-it/master-coverage-band-details-wcseo

Master coverage band details wcseo
This commit is contained in:
Carlo Cancellieri 2014-02-18 17:11:00 +01:00
commit 7d5d159b55
24 changed files with 1558 additions and 818 deletions

View File

@ -1821,12 +1821,9 @@ public class GeoServerRESTPublisher {
throw new IllegalArgumentException("no coverageEncoder provided for mosaic "
+ mosaicDir);
}
// override name to match the FIRST configured coverage
String coverageName = coverageEncoder.getName();
if (layerEncoder == null) {
throw new IllegalArgumentException("no layerEncoder provided for " + workspace + ":"
+ coverageName);
throw new IllegalArgumentException("no layerEncoder provided for " + mosaicDir);
}
RESTCoverageStore store = createExternaMosaicDatastore(workspace, storeName, mosaicDir,
@ -1835,6 +1832,13 @@ public class GeoServerRESTPublisher {
if (store == null) {
return false;
}
// override name to match the FIRST configured coverage
String coverageName = coverageEncoder.getName();
if (coverageName==null){
coverageName=mosaicDir.getName();
coverageEncoder.setName(coverageName);
}
if (!createCoverage(workspace, storeName, coverageEncoder)) {
if (LOGGER.isErrorEnabled())
LOGGER.error("Unable to create a coverage for the store:" + coverageName);
@ -2129,6 +2133,8 @@ public class GeoServerRESTPublisher {
*/
private void deleteStylesForWorkspace(String workspace) {
RESTStyleList styles = styleManager.getStyles(workspace);
if (styles==null)
return;
for (NameLinkElem nameLinkElem : styles) {
removeStyleInWorkspace(workspace, nameLinkElem.getName(), true);
}

View File

@ -26,13 +26,13 @@
package it.geosolutions.geoserver.rest.decoder;
import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.FeatureTypeAttribute;
import it.geosolutions.geoserver.rest.encoder.feature.GSAttributeEncoder;
import it.geosolutions.geoserver.rest.encoder.metadatalink.GSMetadataLinkInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadatalink.ResourceMetadataLinkInfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -43,8 +43,9 @@ import org.jdom.Namespace;
* Parse a resource (FeatureType or Coverage) returned as XML REST objects.
*
* @author etj
* @author Emmanuel Blondel - emmanuel.blondel1@gmail.com |
* emmanuel.blondel@fao.org
* @author Emmanuel Blondel - emmanuel.blondel1@gmail.com | emmanuel.blondel@fao.org
* @author Henry Rotzoll
*
*/
public class RESTResource {
protected final Element rootElem;
@ -90,7 +91,6 @@ public class RESTResource {
return kwdsList;
}
public String getNameSpace() {
return rootElem.getChild("namespace").getChildText("name");
}
@ -157,7 +157,7 @@ public class RESTResource {
/**
* Decodes the list of MetadataLinkInfo from the GeoServer Resource
*
* @author Emmanuel Blondel
* @since gs-2.4.x
*
* @return the list of GSMetadataLinkEncoder
*/
@ -168,13 +168,15 @@ public class RESTResource {
if (metaLinksRoot != null) {
final List<Element> metaLinks = metaLinksRoot.getChildren();
if (metaLinks != null) {
metaLinksList = new ArrayList<GSMetadataLinkInfoEncoder>(
metaLinks.size());
metaLinksList = new ArrayList<GSMetadataLinkInfoEncoder>(metaLinks.size());
for (Element metaLink : metaLinks) {
final GSMetadataLinkInfoEncoder metaLinkEnc = new GSMetadataLinkInfoEncoder();
metaLinkEnc.setType(metaLink.getChildText(ResourceMetadataLinkInfo.type.name()));
metaLinkEnc.setMetadataType(metaLink.getChildText(ResourceMetadataLinkInfo.metadataType.name()));
metaLinkEnc.setContent(metaLink.getChildText(ResourceMetadataLinkInfo.content.name()));
metaLinkEnc
.setType(metaLink.getChildText(ResourceMetadataLinkInfo.type.name()));
metaLinkEnc.setMetadataType(metaLink
.getChildText(ResourceMetadataLinkInfo.metadataType.name()));
metaLinkEnc.setContent(metaLink.getChildText(ResourceMetadataLinkInfo.content
.name()));
metaLinksList.add(metaLinkEnc);
}
@ -183,4 +185,46 @@ public class RESTResource {
return metaLinksList;
}
/**
* Decodes the list of GSCoverageDimensionEncoder from the GeoServer Resource
*
* @since gs-2.4.x
*
* @return the list of GSCoverageDimensionEncoder
*/
public List<GSCoverageDimensionEncoder> getEncodedDimensionsInfoList() {
List<GSCoverageDimensionEncoder> dimensionList = null;
final Element dimensionsRoot = rootElem.getChild("dimensions");
if (dimensionsRoot != null) {
final List<Element> dimensions = dimensionsRoot.getChildren();
if (dimensions != null) {
dimensionList = new ArrayList<GSCoverageDimensionEncoder>(dimensions.size());
for (Element coverageDimension : dimensions) {
final String name = coverageDimension.getChildText("name");
final String description = coverageDimension.getChildText("description");
String rangeMin = null;
String rangeMax = null;
final Element rangeElement = coverageDimension.getChild("range");
if (rangeElement != null) {
rangeMin = rangeElement.getChildText("min");
rangeMax = rangeElement.getChildText("max");
}
final String unit = coverageDimension.getChildText("unit");
String dimensionTypeName = null;
final Element dimensionTypeElement = coverageDimension
.getChild("dimensionType");
if (dimensionTypeElement != null) {
dimensionTypeName = dimensionTypeElement.getChildText("name");
}
final GSCoverageDimensionEncoder coverageDimensionEncoder = new GSCoverageDimensionEncoder(
name, description, rangeMin, rangeMax, unit, dimensionTypeName);
dimensionList.add(coverageDimensionEncoder);
}
}
}
return dimensionList;
}
}

View File

@ -133,12 +133,21 @@ public class GSVersionDecoder extends XmlElement {
return VERSION.getVersion(e.getTextTrim());
}
/**
* @see {@link Enum#compareTo(Enum)}
* @param v
* @return
*/
public int compareTo(VERSION v) {
return getVersion().compareTo(v);
}
public static GSVersionDecoder build(String response) {
return new GSVersionDecoder(response);
}
public enum VERSION {
v22(22), v23(23), v24(24), v25(25), ABOVE(9999), UNRECOGNIZED(-1);
UNRECOGNIZED(-1), v22(22), v23(23), v24(24), v25(25), ABOVE(9999);
final private int version;

View File

@ -41,6 +41,34 @@ import org.jdom.filter.Filter;
*
* The layer encoder is enabled by default
*
* {@code
* <layer>
* <name>{LAYERNAME}</name>
* <type>RASTER</type>
* <defaultStyle>
* <name>{STYLE_NAME}</name>
* <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://{GSURL}/rest/styles/{STYLE}xml" type="application/xml"/>
* </defaultStyle>
* <resource class="coverage">
* <name>{RESOURCE_NAME}</name>
* <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate"
* href="http://{GSURL}/rest/workspaces/{WS}/coveragestores/{STORE}/coverages/{LAYER}.xml" type="application/xml"/>
* </resource>
* <attribution>
* <title>test</title>
* <href>http://www.fao.org/fileadmin/templates/faoweb/images/FAO-logo.png</href>
* <logoURL>http://www.fao.org/fileadmin/templates/faoweb/images/FAO-logo.png</logoURL>
* <logoWidth>412</logoWidth>
* <logoHeight>77</logoHeight>
* <logoType>image/png</logoType>
* </attribution>
* ...
*
* </layer>
* }
*
*
* @since gs-2.2.x
*/
public class GSLayerEncoder extends PropertyXMLEncoder {

View File

@ -45,6 +45,8 @@ import it.geosolutions.geoserver.rest.encoder.utils.XmlElement;
*
* The layer encoder is enabled by default
*
* @since gs-2.1.x
*
*/
public class GSLayerEncoder21 extends GSLayerEncoder {

View File

@ -47,19 +47,24 @@ import org.jdom.filter.Filter;
*
* @author ETj (etj at geo-solutions.it)
* @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it
* @author Emmanuel Blondel - emmanuel.blondel1@gmail.com |
* emmanuel.blondel@fao.org
* @author Emmanuel Blondel - emmanuel.blondel1@gmail.com | emmanuel.blondel@fao.org
* @author Henry Rotzoll
*/
public abstract class GSResourceEncoder
extends PropertyXMLEncoder {
public abstract class GSResourceEncoder extends PropertyXMLEncoder {
public final static String NAME = "name";
public final static String NATIVENAME = "nativeName";
public final static String METADATA = "metadata";
public final static String KEYWORDS = "keywords";
public final static String METADATALINKS = "metadataLinks";
final private GSMetadataEncoder metadata = new GSMetadataEncoder();
final private Element keywordsListEncoder = new Element(KEYWORDS);
final private Element metadataLinksListEncoder = new Element(METADATALINKS);
private class GSMetadataEncoder extends NestedElementEncoder {
@ -69,8 +74,7 @@ public abstract class GSResourceEncoder
}
/**
* @param rootName
* Actually 'feature' or 'coverage'
* @param rootName Actually 'feature' or 'coverage'
* @see GSFeatureTypeEncoder
* @see GSCoverageEncoder
*/
@ -88,7 +92,6 @@ public abstract class GSResourceEncoder
set("enabled", (enabled) ? "true" : "false");
}
/**
* @param key
* @param dimensionInfo
@ -121,7 +124,8 @@ public abstract class GSResourceEncoder
* @param dimensionInfo {@link GSDimensionInfoEncoder} with additional information about the dimension
* @param custom is the dimension custom or not?
*/
protected void addMetadataDimension(String key, GSDimensionInfoEncoder dimensionInfo, boolean custom) {
protected void addMetadataDimension(String key, GSDimensionInfoEncoder dimensionInfo,
boolean custom) {
if (custom) {
metadata.set("custom_dimension_" + key.toUpperCase(), dimensionInfo.getRoot());
} else {
@ -133,6 +137,10 @@ public abstract class GSResourceEncoder
setMetadataDimension(key, dimensionInfo, false);
}
public void setMetadataString(String key, String value) {
metadata.set(key, value);
}
/**
* Set the metadata for a custom dimension.
*
@ -140,27 +148,43 @@ public abstract class GSResourceEncoder
* @param dimensionInfo {@link GSDimensionInfoEncoder} with additional information about the dimension
* @param custom is the dimension custom or not?
*/
public void setMetadataDimension(String key, GSDimensionInfoEncoder dimensionInfo, boolean custom) {
public void setMetadataDimension(String key, GSDimensionInfoEncoder dimensionInfo,
boolean custom) {
if (custom) {
metadata.set("custom_dimension_" + key.toUpperCase(), dimensionInfo.getRoot());
} else {
metadata.set(key, dimensionInfo.getRoot());
}
}
/**
* @param key
* the name of the metadata to add (f.e.: elevation, time)
* @param key the name of the metadata to add (f.e.: elevation, time)
* @return true if something is removed, false otherwise
*/
public boolean delMetadata(String key) {
return metadata.remove(key);
}
public void addKeyword(String keyword) {
final Element el = new Element("string");
el.setText(keyword);
keywordsListEncoder.addContent(el);
checkKeyword(keyword);
putKeyword(keyword);
}
/**
* {@code
* <keywords>
* <string>WCS</string>
* <string>ImageMosaic</string>
* <string>srtm30</string> <string> KEYWORD}\@language={LANGUAGE}\;\@vocabulary={VOCABULARY}\;</string>
* <string>{KEYWORD_2}\@vocabulary={VOCABULARY_2}\;</string> <string>{KEYWORD_3}\@language={LANGUAGE_3}\;</string> </keywords> }
*
* @param keyword mandatory keyword ('\' characters are not permitted)
* @param language optional parameter
* @param vocabulary optional parameter
*/
public void addKeyword(final String keyword, final String language, final String vocabulary) {
checkKeyword(keyword);
putKeyword(buildKeyword(keyword, language, vocabulary));
}
/**
@ -170,13 +194,28 @@ public abstract class GSResourceEncoder
* @return true if something is removed, false otherwise
*/
public boolean delKeyword(final String keyword) {
final Element el = new Element("string");
el.setText(keyword);
return removeKeyword(keyword, null, null);
}
/**
* delete a keyword from the list
*
* @param keyword
* @return true if something is removed, false otherwise
*/
public boolean delKeyword(final String keyword, final String language, final String vocabulary) {
return removeKeyword(keyword, language, vocabulary);
}
private boolean removeKeyword(final String keyword, final String language,
final String vocabulary) {
checkKeyword(keyword);
final String text = buildKeyword(keyword, language, vocabulary);
return (keywordsListEncoder.removeContent(new Filter() {
private static final long serialVersionUID = 1L;
public boolean matches(Object obj) {
if (((Element) obj).getText().equals(keyword)) {
if (((Element) obj).getText().equals(text)) {
return true;
}
return false;
@ -184,12 +223,36 @@ public abstract class GSResourceEncoder
})).size() == 0 ? false : true;
}
private void putKeyword(String keyword) {
final Element el = new Element("string");
el.setText(keyword);
keywordsListEncoder.addContent(el);
}
private void checkKeyword(String keyword) {
if (keyword == null || keyword.isEmpty() || keyword.contains("\\")) {
throw new IllegalArgumentException("keyword may not be null, empty or contains '\'");
}
}
private String buildKeyword(final String keyword, final String language, final String vocabulary) {
StringBuilder sb = new StringBuilder(keyword);
// \@language={LANGUAGE_3}\;
if (language != null && !language.isEmpty()) {
sb.append("\\@language=").append(language).append("\\;");
}
// \@vocabulary={VOCABULARY}\;
if (vocabulary != null && !vocabulary.isEmpty()) {
sb.append("\\@vocabulary=").append(vocabulary).append("\\;");
}
return sb.toString();
}
/**
* Adds a MetadataLinkInfo to the GeoServer Resource
*
* @param MetadataLink
*
* @author Emmanuel Blondel
*/
public void addMetadataLinkInfo(GSMetadataLinkInfoEncoder metadataLinkInfo) {
metadataLinksListEncoder.addContent(metadataLinkInfo.getRoot());
@ -198,36 +261,28 @@ public abstract class GSResourceEncoder
/**
* Adds quickly a MetadataLinkInfo to the GeoServer Resource
*
* @author Emmanuel Blondel
*
* @param type
* @param metadataType
* @param content
*/
public void addMetadataLinkInfo(String type, String metadataType,
String content) {
final GSMetadataLinkInfoEncoder mde = new GSMetadataLinkInfoEncoder(
type, metadataType, content);
public void addMetadataLinkInfo(String type, String metadataType, String content) {
final GSMetadataLinkInfoEncoder mde = new GSMetadataLinkInfoEncoder(type, metadataType,
content);
metadataLinksListEncoder.addContent(mde.getRoot());
}
/**
* Deletes a metadataLinkInfo from the list using the metadataURL
* (MetadataLinkInfo content)
*
* @author Emmanuel Blondel
* Deletes a metadataLinkInfo from the list using the metadataURL (MetadataLinkInfo content)
*
* @param metadataURL
* @return true if something is removed, false otherwise
*/
public boolean delMetadataLinkInfo(final String metadataURL) {
return (metadataLinksListEncoder
.removeContent(GSMetadataLinkInfoEncoder
.getFilterByContent(metadataURL))).size() == 0 ? false
: true;
return (metadataLinksListEncoder.removeContent(GSMetadataLinkInfoEncoder
.getFilterByContent(metadataURL))).size() == 0 ? false : true;
}
/**
* Reprojection policy for a published layer. One of:
* <ul>
@ -288,7 +343,6 @@ public abstract class GSResourceEncoder
return null;
}
/**
* Add the 'nativename' node with a text value from 'name'
*
@ -298,19 +352,16 @@ public abstract class GSResourceEncoder
add(NATIVENAME, nativename);
}
/**
* Set or modify the 'nativename' node with a text value from 'name'
*
* @note if not specified, the nativeName will be set with the value of the
* 'name' node.
* @note if not specified, the nativeName will be set with the value of the 'name' node.
*
*/
public void setNativeName(final String nativename) {
set(NATIVENAME, nativename);
}
/**
* Get the nativeName
*
@ -324,7 +375,6 @@ public abstract class GSResourceEncoder
return null;
}
private final static String DESCRIPTION = "description";
/**
@ -343,6 +393,7 @@ public abstract class GSResourceEncoder
}
private final static String ABSTRACT = "abstract";
/**
* Add the 'abstract' node with a text value from 'abstract'
*
@ -350,6 +401,7 @@ public abstract class GSResourceEncoder
protected void addAbstract(final String _abstract) {
add(ABSTRACT, _abstract);
}
/**
* Set or modify the 'abstract' node with a text value from 'abstract'
*/
@ -407,9 +459,13 @@ public abstract class GSResourceEncoder
}
private final static String LATLONBBMINX = "latLonBoundingBox/minx";
private final static String LATLONBBMAXX = "latLonBoundingBox/maxx";
private final static String LATLONBBMINY = "latLonBoundingBox/miny";
private final static String LATLONBBMAXY = "latLonBoundingBox/maxy";
private final static String LATLONBBCRS = "latLonBoundingBox/crs";
/**
@ -420,8 +476,8 @@ public abstract class GSResourceEncoder
* @param miny
* @param crs
*/
protected void addLatLonBoundingBox(double minx, double miny, double maxx,
double maxy, final String crs) {
protected void addLatLonBoundingBox(double minx, double miny, double maxx, double maxy,
final String crs) {
add(LATLONBBMINX, String.valueOf(minx));
add(LATLONBBMINY, String.valueOf(miny));
add(LATLONBBMAXY, String.valueOf(maxy));
@ -429,8 +485,8 @@ public abstract class GSResourceEncoder
add(LATLONBBCRS, crs);
}
public void setLatLonBoundingBox(double minx, double miny, double maxx,
double maxy, final String crs) {
public void setLatLonBoundingBox(double minx, double miny, double maxx, double maxy,
final String crs) {
set(LATLONBBMINX, String.valueOf(minx));
set(LATLONBBMAXY, String.valueOf(maxy));
set(LATLONBBMAXX, String.valueOf(maxx));
@ -439,9 +495,13 @@ public abstract class GSResourceEncoder
}
private final static String NATIVEBBMINX = "nativeBoundingBox/minx";
private final static String NATIVEBBMAXX = "nativeBoundingBox/maxx";
private final static String NATIVEBBMINY = "nativeBoundingBox/miny";
private final static String NATIVEBBMAXY = "nativeBoundingBox/maxy";
private final static String NATIVEBBCRS = "nativeBoundingBox/crs";
/**
@ -451,8 +511,8 @@ public abstract class GSResourceEncoder
* @param miny
* @param crs
*/
protected void addNativeBoundingBox(double minx, double miny, double maxx,
double maxy, final String crs) {
protected void addNativeBoundingBox(double minx, double miny, double maxx, double maxy,
final String crs) {
add(NATIVEBBMINX, String.valueOf(minx));
add(NATIVEBBMAXY, String.valueOf(maxy));
add(NATIVEBBMAXX, String.valueOf(maxx));
@ -460,8 +520,8 @@ public abstract class GSResourceEncoder
add(NATIVEBBCRS, crs);
}
public void setNativeBoundingBox(double minx, double miny, double maxx,
double maxy, final String crs) {
public void setNativeBoundingBox(double minx, double miny, double maxx, double maxy,
final String crs) {
set(NATIVEBBMINX, String.valueOf(minx));
set(NATIVEBBMAXY, String.valueOf(maxy));
set(NATIVEBBMAXX, String.valueOf(maxx));

View File

@ -25,9 +25,12 @@
package it.geosolutions.geoserver.rest.encoder.coverage;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder;
import org.jdom.Element;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils;
/**
* Creates an XML
@ -38,6 +41,10 @@ import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder;
*/
public class GSCoverageEncoder extends GSResourceEncoder {
public final static String DIMENSIONS = "dimensions";
final private Element dimensionsEncoder = new Element(DIMENSIONS);
public GSCoverageEncoder() {
super("coverage");
}
@ -59,4 +66,44 @@ public class GSCoverageEncoder extends GSResourceEncoder {
public void setMetadata(String key, GSDimensionInfoEncoder dimensionInfo) {
super.setMetadata(key, dimensionInfo);
}
/**
* Adds a CoverageDimensionInfo to the GeoServer Resource
*
* @param coverageDimensionInfo
*
*/
public void addCoverageDimensionInfo(GSCoverageDimensionEncoder coverageDimensionInfo) {
if (ElementUtils.contains(getRoot(), DIMENSIONS) == null)
addContent(dimensionsEncoder);
dimensionsEncoder.addContent(coverageDimensionInfo.getRoot());
}
/**
* Adds quickly a CoverageDimensionInfo to the GeoServer Resource
*
* @param name
* @param description
* @param rangeMin
* @param rangeMax
* @param unit
* @param dimensionType
*/
public void addCoverageDimensionInfo(String name, String description, String rangeMin,
String rangeMax, String unit, String dimensionType) {
final GSCoverageDimensionEncoder coverageDimensionEncoder = new GSCoverageDimensionEncoder(
name, description, rangeMin, rangeMax, unit, dimensionType);
addCoverageDimensionInfo(coverageDimensionEncoder);
}
/**
* Deletes a CoverageDimensionInfo from the list using the CoverageDimension Name (CoverageDimensionInfo content)
*
* @param coverageDimensionName
* @return true if something is removed, false otherwise
*/
public boolean delCoverageDimensionInfo(final String coverageDimensionName) {
return (dimensionsEncoder.removeContent(GSCoverageDimensionEncoder
.getFilterByContent(coverageDimensionName))).size() == 0 ? false : true;
}
}

View File

@ -0,0 +1,393 @@
/*
* GeoServer-Manager - Simple Manager Library for GeoServer
*
* Copyright (C) 2007,2011 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package it.geosolutions.geoserver.rest.encoder.dimensions;
import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils;
import it.geosolutions.geoserver.rest.encoder.utils.XmlElement;
import org.jdom.Element;
import org.jdom.filter.Filter;
/**
* GSCoverageDimension - encodes a CoverageDimension for a given GeoServer Resource (feature type /coverage), as follows:
*
* <pre>
* {@code
* final GSCoverageDimensionEncoder gsCoverageDimensionEncoder =
* new GSCoverageDimensionEncoder("GRAY_INDEX", "GridSampleDimension[-2.147483648E9,-2.147483648E9]",
* String.valueOf(Integer.MIN_VALUE), String.valueOf(Integer.MAX_VALUE), "dobson units³", "REAL_32BITS");
* coverageEncoder.addCoverageDimensionInfo(gsCoverageDimensionEncoder);
* }
* </pre>
*
* For this example, the XML output is:
*
* <pre>
* {@code
* <coverageDimension>
* <name>GRAY_INDEX</name>
* <description>GridSampleDimension[-2.147483648E9,2.147483648E9]</description>
* <range>
* <min>-2.147483648E9</min>
* <max>2.147483647E9</max>
* </range>
* <unit>dobson units³</unit>
* <dimensionType>
* <name>REAL_32BITS</name>
* </dimensionType>
* </coverageDimension>
* }
* </pre>
*
* @author Henry Rotzoll (henry.rotzoll@dlr.de)
*
*/
public class GSCoverageDimensionEncoder extends XmlElement {
/**
* A class to filter the GSCoverageDimension by content
*
*
*/
private static class filterByContent implements Filter {
final private String key;
public filterByContent(String content) {
this.key = content;
}
private static final long serialVersionUID = 1L;
public boolean matches(Object obj) {
Element el = ((Element) obj).getChild("name");
if (el != null && el.getTextTrim().equals(key)) {
return true;
}
return false;
}
}
/**
* Get a Filter using the GSCoverageDimensionEncoder content (GSCoverageDimensionEncoder name)
*
* @param content
* @return the filter
*/
public static Filter getFilterByContent(String content) {
return new filterByContent(content);
}
/**
* Constructs a new GSCoverageDimensionEncoder
*
*/
public GSCoverageDimensionEncoder() {
super("coverageDimension");
}
/**
* Constructs quickly a GSCoverageDimensionEncoder info
*
* @param name
* @param description
* @param rangeMin
* @param rangeMax
* @param unit
* @param dimensionTypeName
*/
public GSCoverageDimensionEncoder(String name, String description, String rangeMin,
String rangeMax, String unit, String dimensionTypeName) {
super("coverageDimension");
this.setup(name, description, rangeMin, rangeMax, unit, dimensionTypeName);
}
/**
* Set-up quickly a GSCoverageDimensionEncoder info
*
* @param name
* @param description
* @param rangeMin
* @param rangeMax
* @param unit
* @param dimensionTypeName
*/
protected void setup(String name, String description, String rangeMin, String rangeMax,
String unit, String dimensionTypeName) {
// name
setName(name);
// description
setDescription(description);
// range
setRange(rangeMin, rangeMax);
// unit
setUnit(unit);
// dimension Type
setDimensionType(dimensionTypeName);
}
/**
* Get the value of the GSCoverageDimensionEncoder member
*
* @param memberName
* @return the value of the GSCoverageDimensionEncoder member
*/
protected String getMember(String memberName) {
Element el = this.getRoot().getChild(memberName.toString());
if (el != null)
return el.getTextTrim();
else
return null;
}
/**
* Deletes a GSCoverageDimensionEncoder member
*
* @param memberName
* @return true if the GSCoverageDimensionEncoder member is removed
*/
protected boolean delMemberIfExists(String memberName) {
if (ElementUtils.contains(getRoot(), memberName) != null) {
return ElementUtils.remove(this.getRoot(),
this.getRoot().getChild(memberName.toString()));
}
return false;
}
/**
* Set a GSCoverageDimensionEncoder member
*
* @param memberName
* @param memberValue
*/
protected void setMember(String memberName, String memberValue) {
if (memberName != null && !memberName.isEmpty() && memberValue != null
&& !memberValue.isEmpty()) {
delMemberIfExists(memberName); // delete the element if it already exists
addMember(memberName.toString(), memberValue);
}
}
/**
* adds a GSCoverageDimensionEncoder member
*
* @param memberName
* @param memberValue
*/
protected void addMember(String memberName, String memberValue) {
if (memberName != null && !memberName.isEmpty() && memberValue != null
&& !memberValue.isEmpty()) {
set(memberName.toString(), memberValue);
}
}
/**
* Set the name
*
* @param name
*/
public void setName(String name) {
setMember("name", name);
}
/**
* Deletes the name
*
* @param name
* @return true if removed
*/
public boolean delName() {
return this.delMemberIfExists("name");
}
/**
* Get the description
*
* @return description
*/
public String getName() {
return this.getMember("name");
}
/**
* Set the description
*
* @param description
*/
public void setDescription(String description) {
setMember("description", description);
}
/**
* Deletes the description
*
* @param description
* @return true if removed
*/
public boolean delDescription() {
return this.delMemberIfExists("description");
}
/**
* Get the description
*
* @return description
*/
public String getDescription() {
return this.getMember("description");
}
/**
* Set the range
*
* @param range
*/
public void setRange(String rangeMin, String rangeMax) {
if (rangeMin != null && !rangeMin.isEmpty() && rangeMax != null && !rangeMax.isEmpty()) {
remove("range");
final Element rangeElement = new Element("range");
final Element rangeMinElement = new Element("min");
rangeMinElement.setText(rangeMin);
final Element rangeMaxElement = new Element("max");
rangeMaxElement.setText(rangeMax);
rangeElement.addContent(rangeMinElement);
rangeElement.addContent(rangeMaxElement);
addContent(rangeElement);
}
}
/**
* Deletes the range
*
* @param range
* @return true if removed
*/
public boolean delRange() {
return this.delMemberIfExists("range");
}
/**
* Get the range min
*
* @return range min
*/
public String getRangeMin() {
final Element range = this.getRoot().getChild("range");
if (range != null) {
return range.getChildText("min");
}
return null;
}
/**
* Get the range max
*
* @return range max
*/
public String getRangeMax() {
final Element range = this.getRoot().getChild("range");
if (range != null) {
return range.getChildText("max");
}
return null;
}
/**
* Set the unit
*
* @param unit
*/
public void setUnit(String unit) {
setMember("unit", unit);
}
/**
* Deletes the type
*
* @param type
* @return true if removed
*/
public boolean delUnit() {
return this.delMemberIfExists("unit");
}
/**
* Get the unit
*
* @return unit
*/
public String getUnit() {
return this.getMember("unit");
}
/**
* Set the dimensionType
*
* @param dimensionType
*/
public void setDimensionType(String dimensionTypeName) {
if (dimensionTypeName != null && !dimensionTypeName.isEmpty()) {
remove("dimensionType");
final Element dimensionTypeElement = new Element("dimensionType");
final Element dimensionNameElement = new Element("name");
dimensionNameElement.setText(dimensionTypeName);
dimensionTypeElement.addContent(dimensionNameElement);
addContent(dimensionTypeElement);
}
}
/**
* Deletes the dimensionType
*
* @param dimensionType
* @return true if removed
*/
public boolean delDimensionType() {
return this.delMemberIfExists("dimensionType");
}
/**
* Get the dimensionType name
*
* @return dimensionType name
*/
public String getDimensionTypeName() {
final Element dimensionType = this.getRoot().getChild("dimensionType");
if (dimensionType != null) {
return dimensionType.getChildText("name");
}
return null;
}
}

View File

@ -316,7 +316,9 @@ public class GeoServerRESTStyleManager extends GeoServerRESTAbstractManager {
if(styleName.contains(":"))
LOGGER.warn("Style name is going to be changed ["+styleName+"]");
styleName = styleName.replaceAll(":", "_");
styleName = URLEncoder.encode(styleName);
// currently REST interface does't support URLencoded URL
// styleName = URLEncoder.encode(styleName);
String sUrl = buildUrl(null, styleName, null);
if (purge) {

View File

@ -1,7 +1,7 @@
package it.geosolutions.geoserver.decoder;
import it.geosolutions.geoserver.rest.decoder.RESTCoverage;
import it.geosolutions.geoserver.rest.encoder.feature.GSAttributeEncoder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.metadatalink.GSMetadataLinkInfoEncoder;
import java.io.File;
@ -18,11 +18,11 @@ import org.springframework.core.io.ClassPathResource;
* ResourceDecoderTest
*
* @author eblondel
* @author Henry Rotzoll (henry.rotzoll@dlr.de)
*
*/
public class ResourceDecoderTest {
RESTCoverage coverage;
@Before
@ -77,7 +77,8 @@ public class ResourceDecoderTest {
@Test
public void testStoreUrl() {
Assert.assertEquals(coverage.getStoreUrl(), "http://localhost:8080/geoserver/rest/workspaces/topp/coveragestores/granuleTestMosaic.xml");
Assert.assertEquals(coverage.getStoreUrl(),
"http://localhost:8080/geoserver/rest/workspaces/topp/coveragestores/granuleTestMosaic.xml");
}
@Test
@ -93,7 +94,6 @@ public class ResourceDecoderTest {
Assert.assertEquals(coverage.getMaxY(), 90, 0);
}
@Test
public void testMetadataLinkInfo() throws IOException {
@ -111,5 +111,19 @@ public class ResourceDecoderTest {
}
@Test
public void testCoverageDimension() throws IOException {
List<GSCoverageDimensionEncoder> list = coverage.getEncodedDimensionsInfoList();
GSCoverageDimensionEncoder coverageDimension1 = list.get(0);
Assert.assertEquals("GRAY_INDEX", coverageDimension1.getName());
Assert.assertEquals("GridSampleDimension[-Infinity,Infinity]",
coverageDimension1.getDescription());
Assert.assertEquals("-inf", coverageDimension1.getRangeMin());
Assert.assertEquals("inf", coverageDimension1.getRangeMax());
Assert.assertEquals("dobson units³", coverageDimension1.getUnit());
Assert.assertEquals("REAL_32BITS", coverageDimension1.getDimensionTypeName());
}
}

View File

@ -78,10 +78,10 @@ public class VersionDecoderTest extends GeoserverRESTTest {
if (!enabled())
return;
GSVersionDecoder geoserver = reader.getGeoserverVersion();
if (GSVersionDecoder.VERSION.v22.equals(GSVersionDecoder.VERSION.getVersion(VERSION))) {
if (GSVersionDecoder.VERSION.v22.equals(GSVersionDecoder.VERSION.getVersion(GS_VERSION))) {
Assert.assertEquals(geoserver.getVersion(), GSVersionDecoder.VERSION.v22);
} else if (GSVersionDecoder.VERSION.UNRECOGNIZED.equals(GSVersionDecoder.VERSION
.getVersion(VERSION))) {
.getVersion(GS_VERSION))) {
Assert.assertEquals(geoserver.getVersion(), GSVersionDecoder.VERSION.UNRECOGNIZED);
}
// print(dec.getRoot());

View File

@ -32,6 +32,7 @@ import it.geosolutions.geoserver.rest.decoder.RESTFeatureType;
import it.geosolutions.geoserver.rest.decoder.RESTLayer;
import it.geosolutions.geoserver.rest.decoder.RESTLayerGroup;
import it.geosolutions.geoserver.rest.decoder.about.GSVersionDecoder;
import it.geosolutions.geoserver.rest.decoder.about.GSVersionDecoder.VERSION;
import it.geosolutions.geoserver.rest.decoder.utils.NameLinkElem;
import java.net.MalformedURLException;
@ -39,6 +40,8 @@ import java.net.URL;
import java.util.List;
import static org.junit.Assert.*;
import org.jdom.output.EscapeStrategy;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
@ -77,7 +80,7 @@ public abstract class GeoserverRESTTest {
public static final String RESTPW;
// geoserver target version
public static final String VERSION;
public static final String GS_VERSION;
public static URL URL;
@ -95,7 +98,7 @@ public abstract class GeoserverRESTTest {
RESTURL = getenv("gsmgr_resturl", "http://localhost:8080/geoserver");
RESTUSER = getenv("gsmgr_restuser", "admin");
RESTPW = getenv("gsmgr_restpw", "geoserver");
VERSION = getenv("gsmgr_version", "2.4");
GS_VERSION = getenv("gsmgr_version", "2.4");
// These tests will destroy data, so let's make sure we do want to run them
enabled = getenv("gsmgr_resttest", "false").equalsIgnoreCase("true");
@ -132,15 +135,15 @@ public abstract class GeoserverRESTTest {
LOGGER.info("Using geoserver instance " + RESTUSER + ":" + RESTPW + " @ "
+ RESTURL);
}
} else {
} else if (existgs == false){
System.out.println("Failing tests : geoserver not found");
fail("GeoServer not found");
}
GSVersionDecoder v=reader.getGeoserverVersion();
if (!v.getVersion().equals(GSVersionDecoder.VERSION.getVersion(VERSION))){
System.out.println("Failing tests : geoserver version does not match.\nAccepted versions: "+GSVersionDecoder.VERSION.print());
fail("GeoServer version ("+v.getVersion()+") does not match the desired one (+VERSION+)");
if (v.compareTo(VERSION.getVersion(GS_VERSION))!=0){
System.out.println("Failing tests : geoserver version does not match.\nAccepted versions: "+VERSION.print());
fail("GeoServer version ("+v.getVersion()+") does not match the desired one ("+GS_VERSION+")");
}
} else {
System.out.println("Skipping tests ");
@ -186,6 +189,7 @@ public abstract class GeoserverRESTTest {
LOGGER.info("Found " + groups.size() + " layerGroups");
for (String groupName : groups) {
RESTLayerGroup group = reader.getLayerGroup(groupName);
if (groups != null) {
StringBuilder sb = new StringBuilder("Group: ").append(groupName).append(":");
for (NameLinkElem layer : group.getLayerList()) {
sb.append(" ").append(layer);
@ -195,11 +199,12 @@ public abstract class GeoserverRESTTest {
LOGGER.info(sb.toString() + ": removed: " + removed);
assertTrue("LayerGroup not removed: " + groupName, removed);
}
}
}
private void deleteAllLayers() {
List<String> layers = reader.getLayers().getNames();
if (layers != null) {
for (String layerName : layers) {
RESTLayer layer = reader.getLayer(layerName);
if (layer.getType() == RESTLayer.Type.VECTOR)
@ -209,7 +214,7 @@ public abstract class GeoserverRESTTest {
else
LOGGER.error("Unknown layer type " + layer.getType());
}
}
}
private void deleteAllCoverageStores() {
@ -269,11 +274,12 @@ public abstract class GeoserverRESTTest {
protected void deleteAllStyles() {
List<String> styles = reader.getStyles().getNames();
if (styles != null) {
for (String style : styles) {
LOGGER.warn("Deleting Style " + style);
boolean removed = publisher.removeStyle(style, true);
assertTrue("Style not removed " + style, removed);
}
}
}

View File

@ -60,7 +60,7 @@ public class GSArcSDEDatastoreEncoderTest extends StoreIntegrationTest {
public GSArcSDEDatastoreEncoderTest() throws IllegalArgumentException, MalformedURLException {
super(System.getProperty("Ignore", "false").equalsIgnoreCase("true"));
super(System.getProperty("Ignore", "true").equalsIgnoreCase("true"));
}
@Override

View File

@ -61,7 +61,7 @@ public class GSOracleNGDatastoreEncoderTest extends StoreIntegrationTest {
// private final static Logger LOGGER = LoggerFactory.getLogger(GSOracleNGDatastoreEncoderTest.class);
public GSOracleNGDatastoreEncoderTest() throws IllegalArgumentException, MalformedURLException {
super(System.getProperty("pgIgnore", "false").equalsIgnoreCase("true"));
super(System.getProperty("pgIgnore", "true").equalsIgnoreCase("true"));
}

View File

@ -44,10 +44,8 @@ import org.slf4j.LoggerFactory;
* <P>
* Since these tests require a running Store instance, this is more like integration tests.<br/>
*
* For testing that a datastore is properly configured, a layer publication has
* to be attempted. For this, the 'states' data (states shapefile - available in
* testdata/states.zip) has to be imported in the corresponding store.
* Note: For Oracle NG this name has to be uppercase (STATES).
* For testing that a datastore is properly configured, a layer publication has to be attempted. For this, the 'states' data (states shapefile -
* available in testdata/states.zip) has to be imported in the corresponding store. Note: For Oracle NG this name has to be uppercase (STATES).
*
* @author carlo cancellieri - GeoSolutions
* @author emmanuel blondel
@ -71,11 +69,12 @@ public abstract class StoreIntegrationTest extends GeoserverRESTTest {
/**
*
* @param ignore false if this test shoudl be disabled
* @param ignore true if this test should be disabled
* @throws IllegalArgumentException
* @throws MalformedURLException
*/
public StoreIntegrationTest(boolean ignore) throws IllegalArgumentException, MalformedURLException {
public StoreIntegrationTest(boolean ignore) throws IllegalArgumentException,
MalformedURLException {
super();
this.storeManager = new GeoServerRESTStoreManager(URL, RESTUSER, RESTPW);
this.ignore = ignore;
@ -85,7 +84,7 @@ public abstract class StoreIntegrationTest extends GeoserverRESTTest {
@Test
public void testCreateDeleteDatastore() throws IllegalArgumentException, MalformedURLException {
if (!enabled()) {
if (!enabled() || ignore) {
return;
}
deleteAll();
@ -100,11 +99,7 @@ public abstract class StoreIntegrationTest extends GeoserverRESTTest {
boolean created = storeManager.create(DEFAULT_WS, storeEncoder);
if( ! ignore )
assertTrue("Datastore not created", created);
else if( ! created)
LOGGER.error("*** store " + storeName + " has not been created.");
assertTrue("*** store " + storeName + " has not been created.", created);
RESTDataStore datastore = reader.getDatastore(DEFAULT_WS, storeName);
assertNotNull(datastore);
@ -112,12 +107,14 @@ public abstract class StoreIntegrationTest extends GeoserverRESTTest {
// check if the datastore is properly configured in GS for publishing layers
String layername = "states";
if (storeEncoder instanceof GSOracleNGDatastoreEncoder)
layername = layername.toUpperCase();
GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder();
fte.setName(layername);
fte.setTitle(layername);
fte.setNativeName(layername);
fte.setTitle(layername+"_TITLE");
fte.setNativeCRS("EPSG:4326");
fte.setDescription("desc");
fte.setEnabled(true);
@ -127,21 +124,13 @@ public abstract class StoreIntegrationTest extends GeoserverRESTTest {
layerEncoder.setDefaultStyle("polygon");
boolean published = publisher.publishDBLayer(DEFAULT_WS, storeName, fte, layerEncoder);
if(!ignore){
assertTrue("Test layer not published", published);
}else if(!published){
LOGGER.error("*** Test layer "
+ layername
+ " has not been published. Problem in datastore configuration");
}
assertTrue("*** Test layer " + layername
+ " has not been published. Problem in datastore configuration", published);
// removing test
boolean removed = storeManager.remove(DEFAULT_WS, storeEncoder, true);
if( ! ignore )
assertTrue("Datastore not removed", removed);
else if( ! removed )
LOGGER.error("*** Datastore " + storeName + " has not been removed.");
assertTrue("*** Datastore " + storeName + " has not been removed.", removed);
assertTrue(publisher.removeWorkspace(DEFAULT_WS, false));
}
}

View File

@ -21,6 +21,7 @@ package it.geosolutions.geoserver.rest.encoder.coverage;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder.Presentation;
import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils;
@ -105,6 +106,8 @@ public class GSCoverageEncoderTest extends TestCase {
encoder.addKeyword("...");
encoder.addKeyword("KEYWORD_N");
// setting dimensions (into metadata)
final GSDimensionInfoEncoder timeDimension=new GSDimensionInfoEncoder(true);
timeDimension.setPresentation(Presentation.CONTINUOUS_INTERVAL);
encoder.setMetadata("time", timeDimension);
@ -120,6 +123,12 @@ public class GSCoverageEncoderTest extends TestCase {
elevationDimension.setPresentation(Presentation.LIST);
encoder.setMetadata("elevation", elevationDimension);
// setting dimensions (since gs-2.4.x)
GSCoverageDimensionEncoder gsCoverageDimensionEncoder = new GSCoverageDimensionEncoder(
"GRAY_INDEX", "GridSampleDimension[-Infinity,Infinity]", "-inf", "inf",
"dobson units³", "REAL_32BITS");
encoder.addCoverageDimensionInfo(gsCoverageDimensionEncoder);
if (LOGGER.isInfoEnabled())
LOGGER.info(encoder.toString());

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2007 - 2011 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* GPLv3 + Classpath exception
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package it.geosolutions.geoserver.rest.encoder.dimensions;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
import java.io.IOException;
import junit.framework.Assert;
import org.junit.Test;
/**
*
* @author Henry Rotzoll (henry.rotzoll@dlr.de)
*
*/
public class GSCoverageDimensionEncoderTest {
@Test
public void coverageDimensionTest() {
GSCoverageDimensionEncoder encoder = new GSCoverageDimensionEncoder("GRAY_INDEX",
"GridSampleDimension[-Infinity,Infinity]", "-inf", "inf", "dobson units³",
"REAL_32BITS");
Assert.assertEquals("GRAY_INDEX", encoder.getName());
Assert.assertEquals("GridSampleDimension[-Infinity,Infinity]", encoder.getDescription());
Assert.assertEquals("-inf", encoder.getRangeMin());
Assert.assertEquals("inf", encoder.getRangeMax());
Assert.assertEquals("dobson units³", encoder.getUnit());
Assert.assertEquals("REAL_32BITS", encoder.getDimensionTypeName());
Assert.assertTrue(encoder.delName());
Assert.assertTrue(encoder.delDescription());
Assert.assertTrue(encoder.delRange());
Assert.assertTrue(encoder.delUnit());
Assert.assertTrue(encoder.delDimensionType());
Assert.assertNull(encoder.getName());
Assert.assertNull(encoder.getDescription());
Assert.assertNull(encoder.getRangeMin());
Assert.assertNull(encoder.getRangeMax());
Assert.assertNull(encoder.getUnit());
Assert.assertNull(encoder.getDimensionTypeName());
encoder.setName("GRAY_INDEX");
encoder.setDescription("GridSampleDimension[-Infinity,Infinity]");
encoder.setRange("-inf", "inf");
encoder.setUnit("dobson units³");
encoder.setDimensionType("REAL_32BITS");
Assert.assertEquals("GRAY_INDEX", encoder.getName());
Assert.assertEquals("GridSampleDimension[-Infinity,Infinity]", encoder.getDescription());
Assert.assertEquals("-inf", encoder.getRangeMin());
Assert.assertEquals("inf", encoder.getRangeMax());
Assert.assertEquals("dobson units³", encoder.getUnit());
Assert.assertEquals("REAL_32BITS", encoder.getDimensionTypeName());
}
}

View File

@ -21,13 +21,16 @@ package it.geosolutions.geoserver.rest.encoder.feature;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.GeoserverRESTTest;
import it.geosolutions.geoserver.rest.decoder.RESTFeatureType;
import it.geosolutions.geoserver.rest.decoder.RESTLayer;
import it.geosolutions.geoserver.rest.decoder.RESTResource;
import it.geosolutions.geoserver.rest.decoder.about.GSVersionDecoder;
import it.geosolutions.geoserver.rest.decoder.about.GSVersionDecoder.VERSION;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder21;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.authorityurl.GSAuthorityURLInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.identifier.GSIdentifierInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder.Presentation;
@ -52,14 +55,12 @@ import org.springframework.core.io.ClassPathResource;
/**
*
* Note on adding multiple available styles to the GSLayerEncoder: - to run the
* testIntegration(), 2 clones of the "point" style, named "point2" and "point3"
* have to be created.
* Note on adding multiple available styles to the GSLayerEncoder: - to run the testIntegration(), 2 clones of the "point" style, named "point2" and
* "point3" have to be created.
*
* @author ETj (etj at geo-solutions.it)
* @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it
* @author Emmanuel Blondel - emmanuel.blondel1@gmail.com |
* emmanuel.blondel@fao.org
* @author Emmanuel Blondel - emmanuel.blondel1@gmail.com | emmanuel.blondel@fao.org
*/
public class GSFeatureEncoderTest extends GeoserverRESTTest {
protected final static Logger LOGGER = LoggerFactory.getLogger(GSFeatureEncoderTest.class);
@ -76,6 +77,18 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
String storeName = "resttestshp";
String layerName = "cities";
publisher.createWorkspace(DEFAULT_WS);
File zipFile = new ClassPathResource("testdata/resttestshp.zip").getFile();
// test insert
boolean published = publisher.publishShp(DEFAULT_WS, storeName, layerName, zipFile);
assertTrue("publish() failed", published);
assertTrue(existsLayer(layerName));
publisher.publishStyle(new File(new ClassPathResource("testdata").getFile(),
"default_point.sld"));
GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder();
fte.setNativeName(layerName);
fte.setName(layerName + "_NEW");
@ -86,17 +99,14 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
fte.setEnabled(true);
// metadataLink
GSMetadataLinkInfoEncoder metadatalink = new GSMetadataLinkInfoEncoder(
"text/xml", "ISO19115:2003",
"http://www.organization.org/metadata1");
GSMetadataLinkInfoEncoder metadatalink = new GSMetadataLinkInfoEncoder("text/xml",
"ISO19115:2003", "http://www.organization.org/metadata1");
fte.addMetadataLinkInfo(metadatalink);
GSLayerEncoder layerEncoder = null;
if (!GSVersionDecoder.VERSION.getVersion(VERSION).equals(
GSVersionDecoder.VERSION.UNRECOGNIZED)) {
if (VERSION.getVersion(GS_VERSION).compareTo(VERSION.UNRECOGNIZED) > 0) {
layerEncoder = new GSLayerEncoder();
} else if (GSVersionDecoder.VERSION.getVersion(VERSION).equals(
GSVersionDecoder.VERSION.UNRECOGNIZED)) {
} else if (VERSION.getVersion(GS_VERSION).compareTo(VERSION.UNRECOGNIZED) == 0) {
layerEncoder = new GSLayerEncoder21();
}
layerEncoder.setEnabled(true);
@ -108,47 +118,32 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
layerEncoder.addStyle("point3");
// authorityURL
GSAuthorityURLInfoEncoder authorityURL = new GSAuthorityURLInfoEncoder(
"authority1", "http://www.authority1.org");
GSAuthorityURLInfoEncoder authorityURL = new GSAuthorityURLInfoEncoder("authority1",
"http://www.authority1.org");
layerEncoder.addAuthorityURL(authorityURL);
// identifier
GSIdentifierInfoEncoder identifier1 = new GSIdentifierInfoEncoder(
"authority1", "identifier1");
GSIdentifierInfoEncoder identifier2 = new GSIdentifierInfoEncoder(
"authority1", "another_identifier");
GSIdentifierInfoEncoder identifier1 = new GSIdentifierInfoEncoder("authority1",
"identifier1");
GSIdentifierInfoEncoder identifier2 = new GSIdentifierInfoEncoder("authority1",
"another_identifier");
layerEncoder.addIdentifier(identifier1);
layerEncoder.addIdentifier(identifier2);
publisher.createWorkspace(DEFAULT_WS);
File zipFile = new ClassPathResource("testdata/resttestshp.zip")
.getFile();
// test insert
boolean published = publisher.publishShp(DEFAULT_WS, storeName,
layerName, zipFile);
assertTrue("publish() failed", published);
assertTrue(existsLayer(layerName));
publisher.publishStyle(new File(new ClassPathResource("testdata")
.getFile(), "default_point.sld"));
// optionally select the attributes to publish
RESTLayer layer = reader.getLayer(layerName);
RESTResource resource = reader.getResource(layer);
RESTLayer layer = reader.getLayer(DEFAULT_WS, layerName);
RESTFeatureType resource = reader.getFeatureType(layer);
List<GSAttributeEncoder> attrs = resource.getEncodedAttributeList();
assertNotNull(attrs);
for (GSAttributeEncoder enc : attrs) {
fte.setAttribute(enc);
}
assertTrue(publisher.publishDBLayer(DEFAULT_WS, storeName, fte,
layerEncoder));
assertTrue(publisher.publishDBLayer(DEFAULT_WS, storeName, fte, layerEncoder));
}
@Test
public void testFeatureTypeEncoder() {
@ -228,16 +223,22 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
public void testModifyFeature() {
GSFeatureTypeEncoder encoder = new GSFeatureTypeEncoder();
encoder.addKeyword("KEYWORD_1");
encoder.addKeyword("KEYWORD_2");
encoder.addKeyword("KEYWORD_1", "LAN_1", "VOCAB_1");
assertTrue(encoder.delKeyword("KEYWORD_1", "LAN_1", "VOCAB_1"));
encoder.addKeyword("...");
encoder.addKeyword("KEYWORD_N");
assertTrue(encoder.delKeyword("KEYWORD_2"));
assertFalse(encoder.delKeyword("KEYWORD_M"));
encoder.addKeyword("KEYWORD_2");
assertFalse(encoder.delKeyword("KEYWORD_2", "LAN_1", "VOCAB_1"));
assertTrue(encoder.delKeyword("KEYWORD_2"));
// metadataLinkInfo
encoder.addMetadataLinkInfo("text/xml", "ISO19115:2003","http://www.organization.org/metadata1");
encoder.addMetadataLinkInfo("text/html", "ISO19115:2003","http://www.organization.org/metadata2");
encoder.addMetadataLinkInfo("text/xml", "ISO19115:2003",
"http://www.organization.org/metadata1");
encoder.addMetadataLinkInfo("text/html", "ISO19115:2003",
"http://www.organization.org/metadata2");
assertTrue(encoder.delMetadataLinkInfo("http://www.organization.org/metadata2"));
assertFalse(encoder.delMetadataLinkInfo("http://www.organization.org/metadata3"));
@ -252,8 +253,7 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
final String metadata = "elevation";
encoder.setMetadataDimension(metadata, elevationDimension);
elevationDimension.setPresentation(Presentation.DISCRETE_INTERVAL,
BigDecimal.valueOf(10));
elevationDimension.setPresentation(Presentation.DISCRETE_INTERVAL, BigDecimal.valueOf(10));
if (LOGGER.isInfoEnabled())
LOGGER.info(encoder.toString());
@ -274,26 +274,39 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
/**
* Test method for virtual table encoding / SQL view layer integration
*
* Settings information for integration tests
* - test is based on the data used in http://docs.geoserver.org/latest/en/user/data/database/sqlview.html#parameterizing-sql-views
* (states shapefile - available in testdata/states.zip)
* - create a postgis db
* - import the states shapefile (using shp2pgsql or Postgis shapefile uploader)
* - In Geoserver, create a postgis datastore for this DB, with the name "statesdb"
* Settings information for integration tests - test is based on the data used in
* http://docs.geoserver.org/latest/en/user/data/database/sqlview.html#parameterizing-sql-views (states shapefile - available in
* testdata/states.zip) - create a postgis db - import the states shapefile (using shp2pgsql or Postgis shapefile uploader) - In Geoserver, create
* a postgis datastore for this DB, with the name "statesdb"
*
* @throws IOException
*
*/
@Test
public void testSQLViewIntegration(){
public void testSQLViewIntegration() throws IOException {
if (!enabled())
return;
deleteAll();
GeoServerRESTPublisher publisher = new GeoServerRESTPublisher(RESTURL, RESTUSER, RESTPW);
String storeName = "resttestshp";
String layerName = "cities";
String storeName = "statesdb"; //name of the datastore setup for tests
String layerName = "my_sqlviewlayer";
String nativeName = "popstates";
// build the store
publisher.createWorkspace(DEFAULT_WS);
// test insert
File zipFile = new ClassPathResource("testdata/resttestshp.zip").getFile();
boolean published = publisher.publishShp(DEFAULT_WS, storeName, layerName, zipFile);
assertTrue("publish() failed", published);
publisher.publishStyle(new File(new ClassPathResource("testdata").getFile(),
"default_point.sld"));
String nativeName = layerName;
layerName=layerName+"_NEW";
GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder();
fte.setName(layerName);
@ -325,7 +338,6 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
vte.addVirtualTableGeometry(vtGeom);
vte.addVirtualTableParameter(vtParam1);
vte.addVirtualTableParameter(vtParam2);
fte.setMetadataVirtualTable(vte); //Set the virtual table
// modif the vte
vte.delVirtualTableGeometry("the_geom");
@ -335,6 +347,8 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
vte.addVirtualTableParameter(vtParam3);
vte.addKeyColumn("gid");
fte.setMetadataVirtualTable(vte); // Set the virtual table
// Layer encoder
// -------------
GSLayerEncoder layerEncoder = new GSLayerEncoder();
@ -345,7 +359,7 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
// test insert
// ------------
publisher.createWorkspace(DEFAULT_WS);
boolean published = publisher.publishDBLayer(DEFAULT_WS, storeName, fte, layerEncoder);
published = publisher.publishDBLayer(DEFAULT_WS, storeName, fte, layerEncoder);
assertTrue("Publication unsuccessful", published);
assertTrue("Layer does not exist", existsLayer(layerName));

View File

@ -39,27 +39,28 @@ public class GeoServerRESTImageMosaicManagerTest extends GeoserverRESTTest {
if (!enabled()) {
return;
}
deleteAll();
publisher.createWorkspace(DEFAULT_WS);
// crea the manager
GeoServerRESTStructuredGridCoverageReaderManager manager =
new GeoServerRESTStructuredGridCoverageReaderManager(new URL(RESTURL), RESTUSER, RESTPW);
// create mosaic
final String workspaceName = "it.geosolutions";
final String coverageStoreName = "mosaic";
final String coverageName = "mosaic";
final String format = "imagemosaic";
// upload the mosaic
boolean create=manager.create(workspaceName, coverageStoreName,new ClassPathResource("testdata/granules/mosaic.zip").getFile().getAbsolutePath());
boolean create=manager.create(DEFAULT_WS, coverageStoreName,new ClassPathResource("testdata/granules/mosaic.zip").getFile().getAbsolutePath());
assertTrue(create);
// enable dimension
fixDimensions(workspaceName, coverageStoreName, coverageName);
fixDimensions(DEFAULT_WS, coverageStoreName, coverageName);
// check index format
RESTStructuredCoverageIndexSchema indexFormat = manager.getGranuleIndexSchema(workspaceName, coverageName,coverageName);
assertTrue(create);
RESTStructuredCoverageIndexSchema indexFormat = manager.getGranuleIndexSchema(DEFAULT_WS, coverageName,coverageName);
assertNotNull(indexFormat);
assertFalse(indexFormat.isEmpty());
assertEquals(5, indexFormat.size());
@ -95,14 +96,14 @@ public class GeoServerRESTImageMosaicManagerTest extends GeoserverRESTTest {
// get with paging
granulesList = manager.getGranules(workspaceName, coverageStoreName, coverageName , null, 0, 1);
granulesList = manager.getGranules(DEFAULT_WS, coverageStoreName, coverageName , null, 0, 1);
assertNotNull(granulesList);
assertEquals(1, granulesList.size());
assertFalse(granulesList.isEmpty());
granule = granulesList.get(0);
assertNotNull(granule);
granulesList = manager.getGranules(workspaceName, coverageStoreName, coverageName, null, null, 2);
granulesList = manager.getGranules(DEFAULT_WS, coverageStoreName, coverageName, null, null, 2);
assertNotNull(granulesList);
assertEquals(2, granulesList.size());
assertFalse(granulesList.isEmpty());
@ -110,7 +111,7 @@ public class GeoServerRESTImageMosaicManagerTest extends GeoserverRESTTest {
assertNotNull(granule);
// get with no paging
granulesList = manager.getGranules(workspaceName, coverageStoreName, coverageName);
granulesList = manager.getGranules(DEFAULT_WS, coverageStoreName, coverageName);
assertNotNull(granulesList);
assertEquals(4, granulesList.size());
assertFalse(granulesList.isEmpty());
@ -118,21 +119,21 @@ public class GeoServerRESTImageMosaicManagerTest extends GeoserverRESTTest {
assertNotNull(granule);
// examples of filtering with CQL
granulesList = manager.getGranules(workspaceName, coverageStoreName, coverageName, "depth = 100", null, null);
granulesList = manager.getGranules(DEFAULT_WS, coverageStoreName, coverageName, "depth = 100", null, null);
assertNotNull(granulesList);
assertEquals(2, granulesList.size());
assertFalse(granulesList.isEmpty());
granule = granulesList.get(0);
assertNotNull(granule);
granulesList = manager.getGranules(workspaceName, coverageStoreName, coverageName, "depth = 100 AND date='20081101T0000000'", null, null);
granulesList = manager.getGranules(DEFAULT_WS, coverageStoreName, coverageName, "depth = 100 AND date='20081101T0000000'", null, null);
assertNotNull(granulesList);
assertEquals(1, granulesList.size());
assertFalse(granulesList.isEmpty());
granule = granulesList.get(0);
assertNotNull(granule);
granulesList = manager.getGranules(workspaceName, coverageStoreName, coverageName, "location LIKE 'NCOM_wattemp%'", 0, 1);
granulesList = manager.getGranules(DEFAULT_WS, coverageStoreName, coverageName, "location LIKE 'NCOM_wattemp%'", 0, 1);
assertNotNull(granulesList);
assertEquals(1, granulesList.size());
assertFalse(granulesList.isEmpty());
@ -141,21 +142,21 @@ public class GeoServerRESTImageMosaicManagerTest extends GeoserverRESTTest {
// remove by filter
final String fileLocation = "NCOM_wattemp_100_20081101T0000000_12.tiff";
boolean result = manager.removeGranulesByCQL(workspaceName, coverageStoreName, coverageName, "location = '" + fileLocation + "'");
boolean result = manager.removeGranulesByCQL(DEFAULT_WS, coverageStoreName, coverageName, "location = '" + fileLocation + "'");
Assert.assertTrue(result);
granulesList = manager.getGranules(workspaceName, coverageStoreName, coverageName);
granulesList = manager.getGranules(DEFAULT_WS, coverageStoreName, coverageName);
assertNotNull(granulesList);
assertEquals(3, granulesList.size());
assertFalse(granulesList.isEmpty());
assertEquals(4, granulesList.size());
granule = granulesList.get(0);
assertNotNull(granule);
// Readding that granule with harvest
result = manager.harvestExternal(workspaceName, coverageStoreName, format, new ClassPathResource("testdata/granules/NCOM_wattemp_100_20081101T0000000_12.tiff").getFile().getAbsolutePath() );
result = manager.harvestExternal(DEFAULT_WS, coverageStoreName, format, new ClassPathResource("testdata/granules/NCOM_wattemp_100_20081101T0000000_12.tiff").getFile().getAbsolutePath() );
Assert.assertTrue(result);
granulesList = manager.getGranules(workspaceName, coverageStoreName, coverageName, null, null, null);
granulesList = manager.getGranules(DEFAULT_WS, coverageStoreName, coverageName, null, null, null);
assertNotNull(granulesList);
assertEquals(4, granulesList.size());
assertFalse(granulesList.isEmpty());
@ -164,7 +165,7 @@ public class GeoServerRESTImageMosaicManagerTest extends GeoserverRESTTest {
// delete
delete(workspaceName, coverageStoreName);
delete(DEFAULT_WS, coverageStoreName);
}
@ -218,6 +219,8 @@ public class GeoServerRESTImageMosaicManagerTest extends GeoserverRESTTest {
String csname) throws NumberFormatException {
// get current config for the coverage to extract the params we want to set again
final RESTCoverage coverage = reader.getCoverage(wsName, coverageStoreName, csname);
if (coverage==null)
return null;
final Map<String, String> params = coverage.getParametersList();
// prepare and fill the encoder

View File

@ -79,8 +79,8 @@ public class GeoserverRESTDatastoreManagerTest extends StoreIntegrationTest {
private static URL LOCATION_2;
public GeoserverRESTDatastoreManagerTest() throws Exception {
super(true);
LOCATION_1 = new URL("file:data/1");
super(false);
LOCATION_1 = new URL("file:data/shapefiles/");
LOCATION_2 = new URL("file:data/2");
}

View File

@ -108,7 +108,7 @@ public class GeoserverRESTGeoTiffTest extends GeoserverRESTTest {
assertTrue("publish() failed", pub);
double[] bbox = {-103.85, 44.38, -103.62, 44.50};
pub = publisher.publishGeoTIFF(DEFAULT_WS, storeName+"another_complex", "layername_complex", geotiff, "EPSG:4326", ProjectionPolicy.REPROJECT_TO_DECLARED, "raster", bbox);
pub = publisher.publishGeoTIFF(DEFAULT_WS, storeName+"another_complex", storeName+"another_complex", geotiff, "EPSG:4326", ProjectionPolicy.REPROJECT_TO_DECLARED, "raster", bbox);
assertTrue("publish() failed", pub);

View File

@ -29,9 +29,11 @@ package it.geosolutions.geoserver.rest.publisher;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher.ParameterConfigure;
import it.geosolutions.geoserver.rest.GeoserverRESTTest;
import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore;
import it.geosolutions.geoserver.rest.decoder.about.GSVersionDecoder;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy;
import it.geosolutions.geoserver.rest.encoder.coverage.GSImageMosaicEncoder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder.Presentation;
@ -42,6 +44,7 @@ import java.io.IOException;
import org.apache.commons.httpclient.NameValuePair;
import org.junit.Test;
import static org.junit.Assert.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
@ -91,7 +94,7 @@ public class GeoserverRESTImageMosaicTest extends GeoserverRESTTest {
* or create a new one from an existing store:
* publisher.createCoverage(ce, wsname, csname);
*/
coverageEncoder.setName("CoverageName");
// coverageEncoder.setName("time_geotiff");
coverageEncoder.setAllowMultithreading(true);
coverageEncoder.setBackgroundValues("");
@ -105,6 +108,15 @@ public class GeoserverRESTImageMosaicTest extends GeoserverRESTTest {
coverageEncoder.setSRS("EPSG:4326");
coverageEncoder.setSUGGESTED_TILE_SIZE("256,256");
coverageEncoder.setUSE_JAI_IMAGEREAD(true);
GSVersionDecoder v=reader.getGeoserverVersion();
if (v.compareTo(GSVersionDecoder.VERSION.v24)>=0){
GSCoverageDimensionEncoder gsCoverageDimensionEncoder = new GSCoverageDimensionEncoder(
"GRAY_INDEX", "GridSampleDimension[-Infinity,Infinity]", "-inf", "inf",
"dobson units³", "REAL_32BITS");
coverageEncoder.addCoverageDimensionInfo(gsCoverageDimensionEncoder);
}
// activate time
final GSDimensionInfoEncoder time=new GSDimensionInfoEncoder(true);
time.setPresentation(Presentation.LIST);
@ -113,6 +125,8 @@ public class GeoserverRESTImageMosaicTest extends GeoserverRESTTest {
// not active elevation
coverageEncoder.setMetadata("elevation", new GSDimensionInfoEncoder());
assertTrue(publisher.createWorkspace(wsName));
LOGGER.info(coverageEncoder.toString());

View File

@ -62,7 +62,7 @@ public class GeoserverRESTPostgisDatastoreTest extends StoreIntegrationTest {
public GeoserverRESTPostgisDatastoreTest()
throws IllegalArgumentException, MalformedURLException {
super(System.getProperty("pgIgnore", "false").equalsIgnoreCase("true"));
super(System.getProperty("pgIgnore", "true").equalsIgnoreCase("true"));
}

View File

@ -1,11 +1,11 @@
<coverage>
<name>granuleTestMosaic</name>
<nativeName>granuleTestMosaic</nativeName>
<abstract>this is an abstract</abstract>
<namespace>
<name>topp</name>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/namespaces/topp.xml" type="application/xml"/>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate"
href="http://localhost:8080/geoserver/rest/namespaces/topp.xml" type="application/xml" />
</namespace>
<title>granuleTestMosaic</title>
<keywords>
@ -26,13 +26,18 @@
</metadataLink>
</metadataLinks>
<nativeCRS>GEOGCS[&quot;WGS 84&quot;, &#xd;
DATUM[&quot;World Geodetic System 1984&quot;, &#xd;
SPHEROID[&quot;WGS 84&quot;, 6378137.0, 298.257223563, AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]], &#xd;
DATUM[&quot;World Geodetic
System 1984&quot;, &#xd;
SPHEROID[&quot;WGS 84&quot;, 6378137.0,
298.257223563,
AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]], &#xd;
AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]], &#xd;
PRIMEM[&quot;Greenwich&quot;, 0.0, AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]], &#xd;
PRIMEM[&quot;Greenwich&quot;, 0.0,
AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]], &#xd;
UNIT[&quot;degree&quot;, 0.017453292519943295], &#xd;
AXIS[&quot;Geodetic longitude&quot;, EAST], &#xd;
AXIS[&quot;Geodetic latitude&quot;, NORTH], &#xd;
AXIS[&quot;Geodetic
latitude&quot;, NORTH], &#xd;
AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]]</nativeCRS>
<srs>EPSG:4326</srs>
<nativeBoundingBox>
@ -69,7 +74,9 @@
</metadata>
<store class="coverageStore">
<name>granuleTestMosaic</name>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/workspaces/topp/coveragestores/granuleTestMosaic.xml" type="application/xml"/>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate"
href="http://localhost:8080/geoserver/rest/workspaces/topp/coveragestores/granuleTestMosaic.xml"
type="application/xml" />
</store>
<grid dimension="2">
<range>
@ -86,6 +93,20 @@
</transform>
<crs>EPSG:4326</crs>
</grid>
<dimensions>
<coverageDimension>
<name>GRAY_INDEX</name>
<description>GridSampleDimension[-Infinity,Infinity]</description>
<range>
<min>-inf</min>
<max>inf</max>
</range>
<unit>dobson units³</unit>
<dimensionType>
<name>REAL_32BITS</name>
</dimensionType>
</coverageDimension>
</dimensions>
<parameters>
<entry>
<string>AllowMultithreading</string>