Skip to content

Commit

Permalink
[GEOS-8245] Named layer validation for style groups
Browse files Browse the repository at this point in the history
  • Loading branch information
tbarsballe committed Aug 24, 2017
1 parent 5d839b3 commit 9972392
Show file tree
Hide file tree
Showing 9 changed files with 511 additions and 257 deletions.
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.geoserver.catalog;

import org.geoserver.platform.ServiceException;
import org.geotools.styling.NamedStyle;
import org.geotools.styling.Style;
import org.geotools.styling.StyledLayer;
import org.geotools.styling.StyledLayerDescriptor;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* Created by tbarsballe on 2017-08-21.
*/
public class SLDNamedLayerValidator extends SLDVisitorAdapter {

public List<Exception> validationErrors = new ArrayList<>();

public SLDNamedLayerValidator(Catalog catalog, CoordinateReferenceSystem fallbackCrs) {
super(catalog, fallbackCrs);
}

public List<Exception> getValidationErrors() {
return validationErrors;
}

@Override
public SLDNamedLayerValidator apply(StyledLayerDescriptor sld) {
try {
super.apply(sld);
} catch (Exception e) {
validationErrors.add(e);
}
return this;
}

@Override
public PublishedInfo visitNamedLayer(StyledLayer namedLayer) {
PublishedInfo p = catalog.getLayerGroupByName(namedLayer.getName());
if (p == null) {
p = catalog.getLayerByName(namedLayer.getName());
}
if (p == null) {
validationErrors.add(new Exception("No layer or layer group named '" + namedLayer.getName()+ "' found in the catalog"));
}
return p;
}

@Override
public Style visitNamedStyle(StyledLayer layer, NamedStyle namedStyle, LayerInfo info) throws IOException {
StyleInfo s = catalog.getStyleByName(namedStyle.getName());
if (s == null) {
validationErrors.add(new Exception("No style named '" + namedStyle.getName()+ "' found in the catalog"));
}
return s.getStyle();
}

public static List<Exception> validate(Catalog catalog, StyledLayerDescriptor sld) {
return new SLDNamedLayerValidator(catalog, null).apply(sld).getValidationErrors();
}
}
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/** /**
* Adapter implementation of {@link SLDVisitor} * Adapter implementation of {@link SLDVisitor}
*/ */
public class SLDVisitorAdapter extends SLDVisitor { public abstract class SLDVisitorAdapter extends SLDVisitor {
public SLDVisitorAdapter(Catalog catalog, CoordinateReferenceSystem fallbackCrs) { public SLDVisitorAdapter(Catalog catalog, CoordinateReferenceSystem fallbackCrs) {
super(catalog, fallbackCrs); super(catalog, fallbackCrs);
} }
Expand Down
14 changes: 10 additions & 4 deletions src/main/src/main/java/org/vfny/geoserver/util/SLDValidator.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@
*/ */
package org.vfny.geoserver.util; package org.vfny.geoserver.util;


import java.io.BufferedReader; import java.io.*;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL; import java.net.URL;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;


import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.PublishedInfo;
import org.geoserver.catalog.SLDVisitor;
import org.geotools.styling.NamedStyle;
import org.geotools.styling.Style;
import org.geotools.styling.StyledLayer;
import org.geotools.styling.UserLayer;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.xml.sax.EntityResolver; import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException; import org.xml.sax.SAXParseException;
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -19,16 +19,7 @@


import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.geoserver.catalog.CascadeDeleteVisitor; import org.geoserver.catalog.*;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.CatalogFacade;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourcePool;
import org.geoserver.catalog.SLDHandler;
import org.geoserver.catalog.StyleHandler;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.Styles;
import org.geoserver.config.GeoServerDataDirectory; import org.geoserver.config.GeoServerDataDirectory;
import org.geoserver.platform.resource.Resource; import org.geoserver.platform.resource.Resource;
import org.geoserver.rest.PutIgnoringExtensionContentNegotiationStrategy; import org.geoserver.rest.PutIgnoringExtensionContentNegotiationStrategy;
Expand Down Expand Up @@ -429,8 +420,16 @@ public void stylePut(
} }
try { try {
StyledLayerDescriptor sld = format.parse( content, version, null, entityResolver); StyledLayerDescriptor sld = format.parse( content, version, null, entityResolver);
//If there are more than one layers, assume this is a style group and validate accordingly.
if (sld.getStyledLayers().length > 1) {
List<Exception> validationErrors = SLDNamedLayerValidator.validate(catalog, sld);
if (validationErrors.size() > 0) {
throw validationErrors.get(0);
}
}

Style style = Styles.style(sld); Style style = Styles.style(sld);
if( format instanceof SLDHandler){ if( format instanceof SLDHandler && sld.getStyledLayers().length <= 1){
s.setFormat(format.getFormat()); s.setFormat(format.getFormat());
resourcePool.writeStyle(s, style, true); resourcePool.writeStyle(s, style, true);
catalog.save(s); catalog.save(s);
Expand All @@ -446,7 +445,7 @@ public void stylePut(
} }
} }
} }
throw new RestException("Unknown style fomrat '"+contentType+"'", HttpStatus.BAD_REQUEST); throw new RestException("Unknown style format '"+contentType+"'", HttpStatus.BAD_REQUEST);
} }
} }


Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -493,6 +493,49 @@ public void testPutRenameDefault() throws Exception {
assertEquals( 500, response.getStatus() ); assertEquals( 500, response.getStatus() );
} }


@Test
public void testPutAsSLDNamedLayer() throws Exception {
String xml =
"<StyledLayerDescriptor version='1.0.0' " +
" xsi:schemaLocation='http://www.opengis.net/sld StyledLayerDescriptor.xsd' " +
" xmlns='http://www.opengis.net/sld' " +
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
" <NamedLayer>\n" +
" <Name>Streams</Name>\n" + //Reference the Streams layer
" </NamedLayer>\n" +
" <NamedLayer>\n" +
" <Name>RoadSegments</Name>\n" + //2nd, valid layer
" </NamedLayer>\n" +
"</StyledLayerDescriptor>";

MockHttpServletResponse response =
putAsServletResponse( RestBaseController.ROOT_PATH + "/styles/Ponds", xml, SLDHandler.MIMETYPE_10);
assertEquals( 200, response.getStatus() );

assertNotNull( catalog.getStyleByName( "Ponds" ) );
}

@Test
public void testPutAsSLDNamedLayerInvalid() throws Exception {
String xml =
"<StyledLayerDescriptor version='1.0.0' " +
" xsi:schemaLocation='http://www.opengis.net/sld StyledLayerDescriptor.xsd' " +
" xmlns='http://www.opengis.net/sld' " +
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
" <NamedLayer>\n" +
" <Name>Stream</Name>\n" + //invalid layer
" </NamedLayer>\n" +
" <NamedLayer>\n" +
" <Name>Streams</Name>\n" + //valid layer
" </NamedLayer>\n" +
"</StyledLayerDescriptor>";

MockHttpServletResponse response =
putAsServletResponse( RestBaseController.ROOT_PATH + "/styles/Ponds", xml, SLDHandler.MIMETYPE_10);
assertEquals( 400, response.getStatus() );
assertEquals("Invalid style:No layer or layer group named 'Stream' found in the catalog", response.getContentAsString());
}

@Test @Test
public void testStyleNotFoundGloballyWhenInWorkspace() throws Exception { public void testStyleNotFoundGloballyWhenInWorkspace() throws Exception {
testPostToWorkspace(); testPostToWorkspace();
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -35,15 +35,7 @@
import org.apache.wicket.model.Model; import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.geoserver.catalog.Catalog; import org.geoserver.catalog.*;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.ResourcePool;
import org.geoserver.catalog.StyleHandler;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.Styles;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.LayerInfoImpl; import org.geoserver.catalog.impl.LayerInfoImpl;
import org.geoserver.config.GeoServer; import org.geoserver.config.GeoServer;
import org.geoserver.config.GeoServerDataDirectory; import org.geoserver.config.GeoServerDataDirectory;
Expand All @@ -54,6 +46,7 @@
import org.geoserver.web.wicket.CodeMirrorEditor; import org.geoserver.web.wicket.CodeMirrorEditor;
import org.geoserver.web.wicket.GeoServerAjaxFormLink; import org.geoserver.web.wicket.GeoServerAjaxFormLink;
import org.geoserver.web.wicket.ParamResourceModel; import org.geoserver.web.wicket.ParamResourceModel;
import org.geotools.styling.StyledLayerDescriptor;
import org.xml.sax.SAXParseException; import org.xml.sax.SAXParseException;


/** /**
Expand Down Expand Up @@ -412,9 +405,15 @@ private String sldErrorWithLineNo(Exception e) {


List<Exception> validateSLD() { List<Exception> validateSLD() {
try { try {
final String sld = editor.getInput(); final String style = editor.getInput();
ByteArrayInputStream input = new ByteArrayInputStream(sld.getBytes()); ByteArrayInputStream input = new ByteArrayInputStream(style.getBytes());
List<Exception> validationErrors = styleHandler().validate(input, null, getCatalog().getResourcePool().getEntityResolver()); List<Exception> validationErrors = styleHandler().validate(input, null, getCatalog().getResourcePool().getEntityResolver());
input = new ByteArrayInputStream(style.getBytes());
StyledLayerDescriptor sld = styleHandler().parse(input, null, null, getCatalog().getResourcePool().getEntityResolver());
//If there are more than one layers, assume this is a style group and validate accordingly.
if (sld.getStyledLayers().length > 1) {
validationErrors.addAll(SLDNamedLayerValidator.validate(getCatalog(), sld));
}
return validationErrors; return validationErrors;
} catch( Exception e ) { } catch( Exception e ) {
return Arrays.asList( e ); return Arrays.asList( e );
Expand Down

0 comments on commit 9972392

Please sign in to comment.